2012-11-15 2 views
7

Vorrei che Lucene trovasse un documento contenente un termine "bahnhofstr" se cerco "bahnhofstrasse", cioè, io Voglio solo trovare documenti contenenti termini di cui il mio termine di ricerca è un prefisso ma anche documenti che contengono termini che sono essi stessi un prefisso del mio termine di ricerca ...Ricerca di termini nell'indice che sono un prefisso del termine di ricerca o viceversa (!)

Come dovrei fare questo?

+0

correlati (ma senza una risposta adeguata per voi, dice solo: "Sì , puoi "): http: // StackOverflow.it/questions/10671755/lucene-prefix-search-per-indexed-data-through-standard-analyzer – Thilo

+1

Non ho visto la parte vice-versa. Quindi vuoi anche premere "b"? c'è una lunghezza minima? – Thilo

+0

Sì, ci sono casi in cui mi piacerebbe anche premere "b". Immagina un campo "first_name" con il solo contenuto "D" ... –

risposta

0

Penso che una query fuzzy potrebbe essere molto utile per voi. Questo valuterà i termini in base alla distanza di Levenshtein dalla tua richiesta. Se non viene specificata una somiglianza minima, corrisponderà in modo efficace a tutti i termini disponibili. Questo può renderlo meno performante, ma realizza ciò che stai cercando.

Un'interrogazione sfocato è segnalata dal carattere ~, come ad esempio:

firstname:bahnhofstr~ 

O con una somiglianza minima (un numero compreso tra 0 e 1, 0 essendo loosest senza limite minimo)

firstname:bahnhofstr~0.4 

Oppure, se si sta costruendo le proprie query, utilizzare il FuzzyQuery

Questo non è del tutto Esattamente quello che si è specificato, ma è il modo più semplice per avvicinarsi.

Per quanto esattamente quello che stai cercando, non so di una semplice chiamata di Lucene per realizzarlo. Avrei probabilmente solo dividere il termine in una serie di termqueries, che si può rappresentare in una query stringa di qualcosa di simile a:

firstname:b 
firstname:ba 
firstname:bah 
firstname:bahn 
firstname:bahnh 
firstname:bahnho 
firstname:bahnhof 
firstname:bahnhofs 
firstname:bahnhofst 
firstname:bahnhofstr* 

non avrei davvero generare una stringa di query per io stesso, tra l'altro. Vorrei semplicemente costruire gli oggetti TermQuery e PrefixQuery da solo.

Il punteggio sarebbe un po 'distorto, e probabilmente avrei spinto più a lungo le query più lunghe per ottenere un migliore ordinamento, ma questo è il metodo che ti viene in mente per realizzare esattamente quello che stai cercando abbastanza facilmente. Un DisjunctionMaxQuery ti aiuterà a usare qualcosa di simile con altri termini e ad acquisire un punteggio più ragionevole.

Speriamo che una query fuzzy funzioni bene per te. Sembra una soluzione molto più bella.

Un'altra opzione, se avete un sacco di necessità per le query di questo tipo, potrebbe essere, quando l'indicizzazione, i campi tokenize in n-grammi (vedi NGramTokenizer), che consentirebbero di utilizzare efficacemente un NGramPhraseQuery per raggiungere i risultati tu vuoi.

1

Se ho capito bene e la stringa di ricerca è una stringa esatta, è possibile impostare queryParser.setAllowLeadingWildcard(true); in Lucene per consentire ricerche con caratteri jolly iniziali (che possono essere o non essere lenti - li ho visti abbastanza velocemente ma in un caso in cui c'erano solo 60.000 documenti Lucene).

Il vostro esempio sintassi di query potrebbe somigliare:

*bahnhofstr bahnhofstr* 

o forse (non hanno testato questo) solo:

*bahnhofstr*