2012-02-01 16 views
7

Utilizzo un analizzatore di palle di neve per bloccare i titoli di più documenti. Tutto funziona bene, ma le loro sono alcune stranezze.Utilizzo di una combinazione di caratteri jolly e staminali

Esempio:

Una ricerca per "valvo", "valvola", o "valvole" restituisce lo stesso numero di risultati. Questo ha senso poiché l'analizzatore di palle di neve riduce tutto a "valv".

Mi imbatto in problemi quando si utilizza un carattere jolly. Una ricerca per "valvola *" o "valvole *" non restituisce alcun risultato. La ricerca di "valv *" funziona come previsto.

Capisco perché questo sta accadendo, ma non so come risolverlo.

Ho pensato di scrivere un analizzatore che memorizza i token staminali e non. Applicando fondamentalmente due analizzatori e combinando i due flussi di token. Ma non sono sicuro che questa sia una soluzione pratica.

Ho anche pensato di utilizzare AnalyzingQueryParser, ma non so come applicarlo a una query su più campi. Inoltre, l'utilizzo di AnalyzingQueryParser restituirebbe risultati per "valvola" durante la ricerca di "valvole *" e questo non è il comportamento previsto.

Esiste un modo "preferito" di utilizzare sia i caratteri jolly che gli algoritmi di derivazione?

risposta

7

Ho usato 2 approccio diverso per risolvere questo prima

  1. Usa due campi, uno che contengono termini stelo, l'altra contenente termini genera esempio, il StandardAnalyzer. Quando si analizza la query di ricerca se è una ricerca con caratteri jolly nel campo "standard", se non si utilizza il campo con termini stemmed. Questo può essere più difficile da utilizzare se l'utente inserisce le sue query direttamente in QueryParser di Lucene.

  2. Scrivere un analizzatore personalizzato e un indice di token sovrapposti. Fondamentalmente consiste nell'indicizzare il termine originale e lo stelo nella stessa posizione dell'indice usando lo PositionIncrementAttribute. È possibile esaminare SynonymFilter per ottenere alcuni esempi su come utilizzare correttamente lo PositionIncrementAttribute.

io preferisco la soluzione # 2.

+0

+1 per la seconda soluzione, è il modo più naturale per farlo. –

1

Non credo che ci sia un modo semplice (e corretto) per farlo.

La mia soluzione sarebbe scrivere un parser di query personalizzato che trova la stringa più lunga comune ai termini nell'indice e ai criteri di ricerca.

class MyQueryParser : Lucene.Net.QueryParsers.QueryParser 
{ 
    IndexReader _reader; 
    Analyzer _analyzer; 

    public MyQueryParser(string field, Analyzer analyzer,IndexReader indexReader) : base(field, analyzer) 
    { 
     _analyzer = analyzer; 
     _reader = indexReader; 
    } 

    public override Query GetPrefixQuery(string field, string termStr) 
    { 
     for(string longestStr = termStr; longestStr.Length>2; longestStr = longestStr.Substring(0,longestStr.Length-1)) 
     { 
      TermEnum te = _reader.Terms(new Term(field, longestStr)); 
      Term term = te.Term(); 
      te.Close(); 
      if (term != null && term.Field() == field && term.Text().StartsWith(longestStr)) 
      { 
       return base.GetPrefixQuery(field, longestStr); 
      } 
     } 

     return base.GetPrefixQuery(field, termStr); 
    } 
} 

si può anche provare a chiamare l'analizzatore in GetPrefixQuery che non si chiama per PrefixQuery s

TokenStream ts = _analyzer.TokenStream(field, new StringReader(termStr)); 
Lucene.Net.Analysis.Token token = ts.Next(); 
var termstring = token.TermText(); 
ts.Close(); 
return base.GetPrefixQuery(field, termstring); 

Ma, essere consapevoli che si può sempre trovare un caso in cui i risultati restituiti non sono corretti. Questo è il motivo per cui Lucene non tiene conto degli analizzatori quando utilizza i caratteri jolly.

+0

Mi piacerebbe davvero trovare un modo per unire due tokenstreams in modo da avere un set di token con gambo e non-gambo ... Ne esaminerò un po '. Aggiornerò se trovo un modo. – SharpBarb

0

L'unica idea potenziale che ho al di là delle altre risposte è quella di utilizzare il dismax nei due campi, quindi è sufficiente impostare i pesi relativi dei due campi. L'unica avvertenza è che alcune versioni di dismax non gestivano i caratteri jolly e alcuni parser sono specifici di Solr.

1

Questa è la soluzione più semplice e sarebbe lavorare -

Aggiungi solr.KeywordRepeatFilterFactory nel vostro analizzatore di 'indice'.

http://lucene.apache.org/core/4_8_0/analyzers-common/org/apache/lucene/analysis/miscellaneous/KeywordRepeatFilterFactory.html

aggiungere anche RemoveDuplicatesTokenFilterFactory alla fine del 'indice' analizzatore

Ora nel tuo indice che si avrà sempre la gambo e la non derivava modulo per ogni gettone sulla stessa posizione e si sono buono per andare.

Problemi correlati