Lucene和特殊字符

10

我正在使用 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;
如果我使用“Name”作为字段进行值为“Test”的搜索,则可以找到文档。但如果我使用相同的搜索条件,但将值更改为“Test(Test)”,则无法找到文档。
更奇怪的是,如果我删除QueryParser.Escape行并搜索一个包含连字符的GUID(当然),它会找到GUID值匹配的文档,但是将值更改为“Test(Test)”进行相同的搜索仍然没有结果。
我不确定自己做错了什么。我正在使用QueryParser.Escape方法来转义特殊字符,并按照Lucene.Net的示例存储字段并进行搜索。你有什么想法吗?
2个回答

5

StandardAnalyzer在索引期间会剥离特殊字符。您可以传入一个明确的停用词列表(排除您想要的停用词)。


我是否应该考虑另一个分析器以实现我的目标?当使用带有特殊字符的字段存储时,是否可以在令牌化和非令牌化之间切换? - Brandon
如果你不对该字段进行标记化处理,就无法在其上“搜索”。你可以有几个选择:编写自己的分析器(非常简单),或将停用词列表传递给StandardAnalyzer。类似于:Hashtable htStopwords = new Hashtable(); Analyzer analyzer = new StandardAnalyzer(htStopwords); - Mikos
你也可以看看StopAnalyzer或SimpleAnalyzer...它们可能会有所帮助。问题是你可能最终会有很多噪音词。但如果这不是问题的话... - Mikos

3
在索引时,您对该字段进行了分词处理。因此,您的输入字符串创建了两个标记“test”和“test”。对于搜索,您手动构建查询,即使用TermQuery而不是QueryParser,后者将对该字段进行分词处理。
要进行完全匹配,您需要对UN_TOKENIZED字段进行索引。在这种情况下,输入字符串被视为单个标记,创建了一个单一的标记“Test(Test)”。在这种情况下,您当前的搜索代码将起作用。您必须仔细注意输入字符串的大小写,以确保在索引小写文本时,搜索时也要相同。
通常最好使用相同的分析器进行索引和搜索。您可以使用KeywordAnalyzer从输入字符串生成单个标记。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接