2017-04-25 4 views
0

J'ai données est segmentée en: -Postgres Stratégie de recherche

  • code postal
  • ville
  • lieu

Mon objectif est de construire une fonction de recherche qui va chercher tout texte donné en utilisant les segmentations ci-dessus dans l'ordre de préséance. c'est à dire. Cherchez d'abord le code postal, puis la ville, puis placez

Est-ce que cela peut être fait efficacement sans devoir scanner complètement le code postal/ville avant de passer à l'endroit? Je peux identifier que le texte est un code postal en utilisant un REGEX, ville et lieu sont plus difficiles.

Je suis heureux de le coder en fonction de plpgsql et a fait quelques progrès avec une stratégie dans ce sens: -

WITH POSTCODES AS (

    SELECT postcode FROM postcode WHERE postcode ~* $1 

), TOWNS AS (

    SELECT town FROM towns WHERE (SELECT * FROM POSTCODES LIMIT 1) IS NULL AND town ~* $1 

), PLACES AS (

    SELECT place FROM places WHERE (SELECT * FROM TOWNS LIMIT 1) IS NULL AND place ~* $1 

) 
SELECT postcode as res FROM POSTCODE 
UNION ALL 
SELECT town as res FROM TOWNS 
UNION ALL 
SELECT place as res FROM PLACES 
+0

Vous pouvez utiliser les index si vous indexez les champs avec un indice de fond ou de gin . Je recommande d'utiliser lower (town) comme lower ($ 1) Puis indexer lower (town) .. Veillez à utiliser ORDER BY ou une autre clause pour vous assurer que le code postal correspond en premier lieu aux villes, puis aux lieux ou à vous peut obtenir des résultats brouillés. Oublié de mentionner, lors de l'indexation, utilisez pg_trgm avec l'index gist/gin. Je peux fournir ceci comme une réponse complète si vous êtes intéressé. –

Répondre

0

Je résolu ce problème en utilisant des pondérations et de combiner mes données dans une seule table avec des colonnes POSTAL, TOWN, PLACE que mes données me permettent de faire.

Je peux ensuite créer une colonne supplémentaire TSV comme: -

setweight(to_tsvector(COALESCE(postcode,'')), 'A') || 
setweight(to_tsvector(COALESCE(town,'')) , 'B') || 
setweight(to_tsvector(COALESCE(place,'')) , 'C') 

Et recherche avec: -

WHERE (tsv @@ plainto_tsquery('SN1 3PF'))