在 Luke 中,以下搜索表达式返回 23 个结果:
docurl:www.siteurl.com docfile:Tomatoes*
如果我通过以下实现将相同的表达式传递到我的 C# Lucene.NET 应用程序中:
IndexReader reader = IndexReader.Open(indexName);
Searcher searcher = new IndexSearcher(reader);
try
{
QueryParser parser = new QueryParser("docurl", new StandardAnalyzer());
BooleanQuery bquery = new BooleanQuery();
Query parsedQuery = parser.Parse(query);
bquery.Add(parsedQuery, Lucene.Net.Search.BooleanClause.Occur.MUST);
int _max = searcher.MaxDoc();
BooleanQuery.SetMaxClauseCount(Int32.MaxValue);
TopDocs hits = searcher.Search(parsedQuery, _max)
...
}
我得到 0 个结果
Luke 正在使用 StandardAnalyzer,这就是解释结构窗口的样子:
BooleanClause
我必须为我搜索的每个字段手动创建对象,为每个字段指定Should
然后将它们添加到BooleanQuery
对象中.Add()
吗?我以为QueryParser
会为我做这件事。我错过了什么?
编辑:
简化一点,docfile:Tomatoes*
在 Luke 返回 23 个文档,但在我的应用程序中返回 0 个。根据 Gene 的建议,我已从更改MUST
为SHOULD
:
QueryParser parser = new QueryParser("docurl", new StandardAnalyzer());
BooleanQuery bquery = new BooleanQuery();
Query parsedQuery = parser.Parse(query);
bquery.Add(parsedQuery, Lucene.Net.Search.BooleanClause.Occur.SHOULD);
int _max = searcher.MaxDoc();
BooleanQuery.SetMaxClauseCount(Int32.MaxValue);
TopDocs hits = searcher.Search(parsedQuery, _max);
parsedQuery 很简单docfile:tomatoes*
编辑2:
我想我终于找到了根本问题:
QueryParser parser = new QueryParser("docurl", new StandardAnalyzer());
Query parsedQuery = parser.Parse(query);
在第二行中,query
是"docfile:Tomatoes*"
,但是parsedQuery
是{docfile:tomatoes*}
。注意到区别了吗?已解析查询中的小写“t”。我以前从未注意到这一点。如果我将 IDE 中的值更改为“T”,则返回 23 个结果。
我已经验证了StandardAnalyzer
在索引和读取索引时正在使用它。我如何强制queryParser
保持值的大小写query
?
Edit3: 哇,多么令人沮丧。根据文档,我可以通过以下方式完成此操作:
parser.setLowercaseExpandedTerms(false);
通配符、前缀、模糊和范围查询的术语是否自动小写。默认为真。
我不会争论这是否是一个明智的默认设置。我想应该使用 SimpleAnalyzer 将索引内外的所有内容小写。令人沮丧的是,至少在我使用的版本中,卢克默认的是另一种方式!至少我了解了更多关于 Lucene 的知识。