Lucene和特殊人物

时间:2010-04-28 20:39:52

标签: c# indexing lucene lucene.net

我使用Lucene.Net 2.0来索引数据库表中的某些字段。其中一个字段是“名称”字段,允许使用特殊字符。当我执行搜索时,它找不到包含带有特殊字符的术语的文档。

我将我的字段编入索引:

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值匹配的文档,但执行相同的搜索,其值为'Test (测试)'仍然没有结果。

我不确定我做错了什么。我正在使用QueryParser.Escape方法来转义特殊字符并存储字段并通过Lucene.Net的示例进行搜索。

有什么想法吗?

2 个答案:

答案 0 :(得分:5)

StandardAnalyzer在索引编制期间删除特殊字符。您可以传入明确的停用词列表(不包括您想要的词)。

答案 1 :(得分:3)

在索引时,您已对该字段进行了标记。因此,您的输入String会创建两个标记“test”和“test”。对于搜索,您正在手动构建查询,即使用TermQuery而不是QueryParser,这将对字段进行标记化。

对于整场比赛,您需要索引字段UN_TOKENIZED。这里,输入字符串被视为单个标记。单个令牌创建“测试(测试)”。在这种情况下,您当前的搜索代码将起作用。您必须仔细观察输入字符串的大小写以确保是否要为小写文本编制索引,您必须在搜索时执行相同的操作。

在索引和搜索过程中使用相同的分析器通常是一种好习惯。您可以使用KeywordAnalyer从输入字符串生成单个标记。