2010-04-28 3 views
9

Ich verwende Lucene.Net 2.0, um einige Felder aus einer Datenbanktabelle zu indizieren. Eines der Felder ist ein 'Name'-Feld, das Sonderzeichen erlaubt. Wenn ich eine Suche durchführe, findet es mein Dokument, das einen Ausdruck mit Sonderzeichen enthält, nicht.Lucene und Sonderzeichen

I Index mein Feld als solche:

Directory DALDirectory = FSDirectory.GetDirectory(@"C:\Indexes\Name", false); 
Analyzer analyzer = new StandardAnalyzer(); 
IndexWriter indexWriter = new IndexWriter(DALDirectory, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED); 

Document doc = new Document(); 
doc.Add(new Field("Name", "Test (Test)", Field.Store.YES, Field.Index.TOKENIZED)); 
indexWriter.AddDocument(doc); 

indexWriter.Optimize(); 
indexWriter.Close(); 

und ich suche Sie folgendermaßen vorgehen:

value = value.Trim().ToLower(); 
value = QueryParser.Escape(value); 

Query searchQuery = new TermQuery(new Term(field, value)); 
Searcher searcher = new IndexSearcher(DALDirectory); 

TopDocCollector collector = new TopDocCollector(searcher.MaxDoc()); 
searcher.Search(searchQuery, collector); 
ScoreDoc[] hits = collector.TopDocs().scoreDocs; 

Wenn ich eine Suche nach Feld als 'Name' und den Wert als 'Test' durchführen, Es findet das Dokument. Wenn ich dieselbe Suche wie "Name" und Wert als "Test (Test)" durchführe, findet es das Dokument nicht.

Noch seltsamer, wenn ich die QueryParser.Escape-Zeile eine Suche nach einer GUID (die natürlich Bindestriche enthält) finden Sie Dokumente, wo der GUID-Wert übereinstimmt, aber die gleiche Suche mit dem Wert als ' Test (Test) 'liefert immer noch keine Ergebnisse.

Ich bin unsicher, was ich falsch mache. Ich verwende die Methode QueryParser.Escape, um die Sonderzeichen zu umgehen, und speichere das Feld und suche nach den Beispielen von Lucene.Net.

Irgendwelche Gedanken?

Antwort

5

Der StandardAnalyzer entfernt die Sonderzeichen während der Indizierung. Sie können eine Liste von expliziten Stoppwörtern übergeben (mit Ausnahme der gewünschten Stoppwörter).

+0

Sollte ich einen anderen Analyzer in Betracht ziehen, um mein Ziel zu erreichen? Was ist mit dem Wechsel zwischen Tokenized zu Un_Tokenized beim Speichern von Feldern mit Sonderzeichen? – Brandon

+0

Nun, wenn Sie das Feld nicht in Token setzen, können Sie nicht darauf "suchen". Sie haben ein paar Möglichkeiten, schreiben Sie Ihren eigenen Analysator (ist sehr einfach) oder übergeben Sie die Liste der Stoppwörter an StandardAnalyzer. etwas wie: Hashtable htStopwords = new Hashtable(); Analysatoranalysator = neuer StandardAnalyzer (htStopwords); – Mikos

+0

Sie können auch auf StopAnalyzer oder SimpleAnalyzer ... sie könnten helfen. Das Problem ist, dass Sie am Ende viele Geräuschwörter haben könnten. Aber wenn das kein Problem ist .... – Mikos

3

Während Index, haben Sie das Feld in Token. Ihre Eingabe String erzeugt also zwei Token "test" und "test". Für die Suche erstellen Sie die Abfrage manuell, dh mit TermQuery anstelle von QueryParser, wodurch das Feld in Token umgewandelt wurde.

Für das gesamte Match müssen Sie das Feld UN_TOKENIZED indizieren. Hier wird die Eingabezeichenfolge als einzelnes Token verwendet. Das einzelne Token erstellt "Test (Test)". In diesem Fall funktioniert Ihr aktueller Suchcode. Sie müssen den Fall der Eingabezeichenfolge genau beobachten, um sicherzustellen, dass Sie bei der Indexierung von Kleinbuchstaben dasselbe tun, während Sie suchen.

Es ist im Allgemeinen eine gute Praxis, denselben Analyzer während der Indizierung und Suche zu verwenden. Sie können mit KeywordAnalyer ein einzelnes Token aus der Eingabezeichenfolge generieren.