2010-02-09 17 views
12

Ceci peut être une question très simpliste, donc des excuses à l'avance, mais je suis très nouveau à l'utilisation de la base de données. Je souhaite que Postgres exécute sa recherche de texte intégral sur plusieurs tables jointes. Imaginez quelque chose comme un utilisateur modèle, avec les modèles connexes UserProfile et UserInfo. La recherche ne concernerait que les utilisateurs, mais inclurait des informations provenant de UserProfile et UserInfo.Postgres recherche de texte intégral à travers plusieurs tables connexes

Je prévois d'utiliser un index de gin pour la recherche. Cependant, je ne sais pas si je vais avoir besoin d'une colonne tsvector séparée dans la table User pour contenir les tsvectors agrégés à travers les tables, et pour configurer les triggers pour les maintenir à jour. Ou s'il est possible de créer un index sans une colonne tsvector qui se tiendra à jour chaque fois que l'un des champs pertinents dans l'une des tables pertinentes change. En outre, tous les conseils sur la syntaxe de la commande pour créer tout cela seraient également très appréciés.

Répondre

8

Votre meilleure réponse est probablement d'avoir une colonne tsvector séparée dans chaque table (avec un index sur, bien sûr). Si vous regroupez les données dans un tsvector partagé, cela créera beaucoup de mises à jour sur celles partagées à chaque mise à jour individuelle.

Vous aurez besoin d'un index par table. Ensuite, lorsque vous l'interrogez, vous avez évidemment besoin de plusieurs clauses WHERE, une pour chaque champ. PostgreSQL déterminera alors automatiquement quelle combinaison d'index utiliser pour vous donner les résultats les plus rapides - probablement en utilisant l'analyse bitmap. Cela rendra vos requêtes un peu plus complexes à écrire (puisque vous avez besoin de plusieurs clauses de correspondance de colonnes), mais cela vous donne la possibilité de seulement interroger certains des champs dans les cas où vous le souhaitez.

Vous ne pouvez pas créer un index qui suit plusieurs tables. Pour ce faire, vous avez besoin de la colonne tsvector séparée et des triggers sur chaque table pour le mettre à jour.

+2

Pouvez-vous entrer dans les détails sur le fonctionnement de la requête de lecture? J'essaie de trouver de la documentation sur la meilleure façon de faire de la recherche en texte intégral postgresql sur plusieurs tables et je ne trouve pas grand-chose. Un problème que j'ai rencontré est que si j'établis un index sur chacune des tables que j'interrogeais, postgresql n'était pas capable d'utiliser tous les index quand j'ai fait une requête. Comme: sélectionnez * à partir des commandes gauche rejoindre sur les utilisateurs ... gauche rejoindre sur line_items ... où ts_vector ('english', orders.id) @@ ... ou ts_vector ('english', users.name) @@. .. –

+1

Je vois aussi qu'une recherche dans deux tables effectue une analyse séquentielle ('SELECT COUNT (*) FROM produits WHERE to_tsvector ('simple', products.name::text) @@ to_tsquery ('simple', 'foo ':: text); '), alors qu'une requête cherchant une table ne fait qu'un scan d'index bitmap en utilisant l'index (' SELECT COUNT (*) FROM produits LEFT JOIN marques ON products.brand_id = brands.id O WH to_tsvector (' simple ' , products.name::text) @@ to_tsquery ('simple', 'foo' :: text) OU to_tsvector ('simple', marques.name::text) @@ to_tsquery ('simple', 'foo' :: texte); – wvengen

Questions connexes