2012-10-25 5 views
15

Sto tentando di eseguire una query fulltext utilizzando Postgresql che può provvedere a corrispondenze parziali utilizzando i caratteri jolly.jolly prefisso Postgresql per il testo completo

Sembra abbastanza facile avere un carattere jolly postfix dopo il termine di ricerca, tuttavia non riesco a capire come specificare un prefisso jolly.

Ad esempio, posso effettuare una ricerca suffisso abbastanza facilmente usando qualcosa di simile ..

SELECT "t1".* 
FROM "t1" 
WHERE (to_tsvector('simple', "t1"."city") @@ to_tsquery('simple', 'don:*')) 

dovrebbe restituire risultati corrispondenti "London"

Tuttavia I cant sembrano fare una ricerca di prefisso come .. .

SELECT "t1".* 
FROM "t1" 
WHERE (to_tsvector('simple', "t1"."city") @@ to_tsquery('simple', ':*don')) 

Idealmente mi piacerebbe avere un jolly prefisso per la parte anteriore e alla fine del termine di ricerca, qualcosa di simile ...

SELECT "t1".* 
FROM "t1" 
WHERE (to_tsvector('simple', "t1"."city") @@ to_tsquery('simple', ':*don:*')) 

Posso utilizzare una condizione LIKE, tuttavia speravo di beneficiare delle prestazioni delle funzionalità di ricerca di testo completo in Postgres.

+2

Secondo il manuale: http://www.postgresql.org/docs/current/static/textsearch-controls.html 'don: *' ** è ** a * prefisso * ricerca. È possibile che si mischi la ricerca prefisso e postfix? –

risposta

9

La ricerca di testo completo è utile per trovare le parole, non le sottostringhe.

Per sottostringa ricerche è meglio utilizzare like '%don%' con pg_trgm estensione disponibile da PostgreSQL 9.1 e using gin (column_name gin_trgm_ops) o using gist (column_name gist_trgm_ops) indici. Ma il tuo indice sarebbe molto grande (anche molte volte più grande del tuo tavolo) e le prestazioni in scrittura non sono molto buone.

C'è uno very good example of using pg_trgm for substring search su select * from depesz blog.

+0

Grazie per la risposta, abbiamo implementato qualcosa di simile già in termini di query, quindi con l'aggiunta dei trigram si spera che questo ci dia il guadagno di prestazioni di cui abbiamo bisogno. Grazie ancora. –

+0

come usare gist (nome_colonna gist_trgm_ops) su 2 colonne invece di una? –

6

Un modo folle e pazzo per farlo sarebbe quello di creare un indice tsvector di tutti i tuoi documenti, invertiti. E rovescia le tue domande anche per la ricerca postfix.

Questo è essenzialmente ciò che Solr fa con la sua ReversedWildcardFilterFactory

select 
reverse('brown fox')::tsvector @@ (reverse('rown') || ':*')::tsquery --true 
+2

Pratico o no, è un trucco malvagio. – Medorator

+1

Sfortunatamente se interrogherete 'row' invece di' rown' non restituirà risultati. Il motivo è che controllerà dall'inizio alla fine, ma di nuovo solo dal primo (ultimo in questa situazione) lettera, e mai dal centro. –

+0

@BernardPotocki non nelle specifiche;) La ricerca di testo completo è abbastanza difficile senza sottostringhe. Se vuoi cercare 'row' e match' brown', allora questo è un buon use-case per regexp –