2010-02-09 20 views
12

Das mag eine sehr simple Frage sein, also Entschuldigung im Voraus, aber ich bin sehr neu in der Datenbanknutzung.Postgres Volltextsuche über mehrere verwandte Tabellen

Ich möchte, dass Postgres seine Volltextsuche über mehrere verbundene Tabellen ausführt. Stellen Sie sich so etwas wie einen Modellbenutzer mit verwandten Modellen UserProfile und UserInfo vor. Die Suche würde nur für Benutzer durchgeführt, würde jedoch Informationen aus UserProfile und UserInfo enthalten.

Ich plane die Verwendung eines GIN-Index für die Suche. Ich bin jedoch unklar, ob ich eine separate tsvector-Spalte in der User-Tabelle benötige, um die aggregierten tsvectors aus den Tabellen aufzunehmen, und um Trigger einzurichten, um sie auf dem neuesten Stand zu halten. Oder wenn es möglich ist, einen Index ohne eine tsvektor-Spalte zu erstellen, die sich immer auf dem neuesten Stand hält, wenn sich eines der relevanten Felder in einer der relevanten Tabellen ändert. Außerdem würden alle Tipps zur Syntax des Befehls, um all dies zu erstellen, sehr geschätzt werden.

Antwort

8

Ihre beste Antwort ist wahrscheinlich eine separate tsvector Spalte in jeder Tabelle (mit einem Index auf, natürlich). Wenn Sie die Daten bis zu einem freigegebenen Tsvector aggregieren, werden viele Updates auf dem freigegebenen erstellt, sobald die einzelnen aktualisiert werden.

Sie benötigen einen Index pro Tabelle. Wenn Sie danach fragen, brauchen Sie natürlich mehrere WHERE-Klauseln, eine für jedes Feld. PostgreSQL wird dann automatisch herausfinden, welche Kombination von Indizes verwendet wird, um Ihnen die schnellsten Ergebnisse zu liefern - wahrscheinlich mit Bitmap-Scans. Dadurch werden Ihre Abfragen etwas komplexer geschrieben (da Sie mehrere Spaltenübereinstimmungsklauseln benötigen), die Flexibilität bleibt jedoch bestehen, nur einige der Felder in den Fällen abzufragen, in denen Sie möchten.

Sie können keinen Index erstellen, der mehrere Tabellen verfolgt. Dazu benötigen Sie die separate tsvector-Spalte und Trigger für jede Tabelle, um sie zu aktualisieren.

+2

Können Sie ins Detail gehen, wie die Leseabfrage funktionieren würde? Ich versuche, eine Dokumentation über die beste Art der Postgresql-Volltextsuche über mehrere Tabellen hinweg zu finden, und ich finde nicht viel. Ein Problem, auf das ich stieß, ist, dass, wenn ich einen Index für jede der Tabellen, die ich abgefragt habe, eingerichtet wurde, war postgresql nicht in der Lage, alle Indizes zu verwenden, wenn ich eine Abfrage machte. Wie folgt: Wählen Sie * aus Bestellungen Links Links Join auf Benutzer ... Links Join auf Line_Elemente ... wobei Ts_Vector ('Englisch', orders.id) @@ ... oder Ts_Vector ('Englisch', users.name) @@. .. –

+1

Ich sehe auch, dass eine Abfrage, die in zwei Tabellen sucht, einen sequentiellen Scan durchführt ('SELECT COUNT (*) FROM Produkte WHERE to_tsvector ('simple', products.name::text) @@ to_tsquery ('simple', 'foo ':: text); '), während eine Abfrage, die nur eine Tabelle durchsucht, eine Bitmap-Indexsuche unter Verwendung des Indexes ausführt (' SELECT COUNT (*) FROM Produkte LINKS JOIN Marken ON products.brand_id = brands.id WHERE to_tsvector (' einfach ' , products.name::text) @@ to_tsquery ('einfach', 'foo' :: text) ODER to_tsvector ('einfach', marken.name::text) @@ to_tsquery ('einfach', 'foo' :: Text); '). – wvengen