2017-05-31 3 views
1

J'ai deux tables simples. Tout d'abord, les marques et chaque marque peut avoir une marque supérieure. Par exemple Elseve a une marque supérieure qui est Loreal Paris. Mais Avon n'a pas de marque supérieure. Et j'ai une table de produits simples.Postgres tsvector avec tables relationnelles

est ici sqlfiddle

Voici la table des marques.

id |  name  | parent_id | depth 
----+--------------+-----------+------- 
    3 | Loreal Paris |  null |  0 
    1 | Avon   |  null |  1 
    2 | Elseve  |  3 |  1 
(3 rows) 

Et voici les produits Table

id | brand_id | name 
----+----------+----------- 
    1 |  1 | Product 1 
    2 |  2 | Product 2 
(2 rows) 

Lorsque je tente d'obtenir tsvectors document produit 1 renvoie un résultat nul. Mais j'ai besoin d'au moins Avon dans le document.

product_id | product_name |      document 
------------+--------------+-------------------------------------------------- 
      1 | Product 1 | 
      2 | Product 2 | '2':2 'elsev':3 'loreal':4 'paris':5 'product':1 
(2 rows) 

Comment résoudre ce problème?

Merci à Voa Tsun. J'ai mis à jour la requête un peu. Je n'ai plus besoin de grouper.

select 
    products.id as product_id, 
    products.name as product_name, 
    to_tsvector(products.name) || 
    to_tsvector(brands.name) || 
    to_tsvector(top_brands.name) 
    as document 
from products 
    JOIN brands on brands.id = products.brand_id 
    LEFT JOIN brands as top_brands on coalesce(brands.parent_id,brands.id) = top_brands.id; 
+0

Vous aurez besoin d'utiliser 'soudent()' quelque part, parce que null' sur l'entrée '' to_tsvector de null'() '' de retour. Voir f.ex. [comment la documentation utilise plusieurs colonnes] (https://www.postgresql.org/docs/current/static/textsearch-controls.html). – pozs

+0

http://rextester.com/SQVSTS56141 comme ici? .. –

+0

Salut @pozs. Je l'ai déjà utilisé. Comme ceci to_tsvector (coalesce (string_agg (top_brands.name, ''))). Je sais que ce n'est pas logique. parce qu'il n'y a pas d'enregistrement top_brand pour Avon. Donc c'est inutile. si j'ajoute top_brand pour toutes les marques, et vide l'enregistrement de nom de top_brand pour les marques qui n'ont pas top_brand, cela fonctionnera. –

Répondre

1

L'idée de base est de se joindre id pas contre nul dans « parent_id », mais « au moins contre id », comme je l'ai reçu de votre poste. comme ici:

select 
     products.id as product_id, 
     products.name as product_name, 
     to_tsvector(coalesce(products.name,brands.name)) || 
     to_tsvector(brands.name) || 
     to_tsvector(coalesce(string_agg(top_brands.name, ' '))) 
     as document 
    from products 
     JOIN brands on brands.id = products.brand_id 
     LEFT JOIN brands as top_brands on coalesce(brands.parent_id,brands.id) = 
    top_brands.id 
    GROUP BY products.id,brands.id; 

    product_id product_name document 
1 1 Product 1 '1':2'avon':3,4'product':1 
2 2 Product 2 '2':2'elsev':3'loreal':4'pari':5'product':1 
+0

Oui. il fonctionne comme un charme. –