2010-04-28 97 views
9

我正在使用Lucene.Net 2.0從數據庫表中索引一些字段。其中一個字段是允許特殊字符的「名稱」字段。當我執行搜索時,它找不到包含具有特殊字符的術語的文檔。Lucene和特殊字符

我索引我的領域這樣:

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(); 

而且我搜索執行以下操作:

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; 

如果我執行現場的「名稱」和值「測試」進行搜索,它找到該文件。如果我執行與「名稱」相同的搜索並將其值設爲「測試(測試)」,則它不會找到該文檔。

更奇怪的是,如果我刪除QueryParser.Escape行,搜索GUID(當然包含連字符),它將找到GUID值匹配的文檔,但執行的值與「測試(測試)'仍然沒有結果。

我不確定我做錯了什麼。我正在使用QueryParser.Escape方法來轉義特殊字符,並存儲該字段並通​​過Lucene.Net的示例進行搜索。

有什麼想法?

回答

5

StandardAnalyzer在索引過程中去掉特殊字符。您可以傳入明確的停用詞列表(不包括您想要的)。

+0

我應該考慮使用另一臺分析儀來實現我的目標嗎? 當存儲帶有特殊字符的字段時,如何在Tokenized和Un_Tokenized之間切換? – Brandon 2010-04-29 02:03:59

+0

好,如果你不標記字段,你不能「搜索」它。你有幾個選擇編寫自己的分析器(非常簡單),或將停用詞表傳遞給StandardAnalyzer。 類似於: Hashtable htStopwords = new Hashtable(); 分析儀分析儀=新的StandardAnalyzer(htStopwords); – Mikos 2010-04-29 02:25:19

+0

你也可以看看StopAnalyzer或SimpleAnalyzer ......他們可能會幫忙。問題在於你最終可能會產生大量噪音。但如果這不是問題.... – Mikos 2010-04-29 02:28:02

3

雖然索引,您已標記該字段。所以,你的輸入字符串會創建兩個標記「test」和「test」。對於搜索,您正在手動構建查詢,即使用TermQuery而不是QueryParser,它將標記字段。

對於整個比賽,你需要索引字段UN_TOKENIZED。這裏,輸入字符串被視爲單個標記。單個標記創建「測試(測試)」。在這種情況下,您當前的搜索代碼將起作用。您必須仔細觀察輸入字符串的大小寫以確保您是否索引小寫文本,您必須在搜索時執行相同操作。

在索引和搜索過程中使用相同的分析器通常是一種很好的做法。您可以使用KeywordAnalyer從輸入字符串生成單個標記。