4

在 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 的建议,我已从更改MUSTSHOULD

            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 的知识。

4

2 回答 2

3

UsingOccur.MUST相当于将+运算符与标准查询解析器一起使用。因此,您的代码正在评估+docurl:www.siteurl.com +docfile:Tomatoes*而不是您在 Luke 中键入的表达式。要获得这种行为,Occur.SHOULD请在添加子句时尝试。

于 2011-05-15T06:00:53.180 回答
1

QueryParser确实会采用像“docurl:www.siteurl.com docfile:Tomatoes*”这样的查询,并根据给定的查询(参见查询语法)从中构建一个适当的查询(布尔查询、范围查询等)。

您的第一步应该是附加调试器并检查parsedQuery.

于 2011-05-13T20:33:46.390 回答