【发布时间】:2016-03-09 15:37:18
【问题描述】:
我正在使用 Lucene.NET 在我们的应用程序中进行全文搜索的概念验证。有些查询工作正常,有些似乎返回的结果与 Luke 工具返回的结果不匹配。更有问题的是,这个查询:
(Description:tasty) (Gtin:00018389732061)
总是产生这个异常:
“System.IndexOutOfRangeException”类型的未处理异常 在 Lucene.Net.Search.TermScorer.Score() 处发生在 Lucene.Net.dll 在 d:\Lucene.Net\FullRepo\trunk\src\core\Search\TermScorer.cs:136 行 在 Lucene.Net.Search.BooleanScorer.BooleanScorerCollector.Collect(Int32 文档)在 d:\Lucene.Net\FullRepo\trunk\src\core\Search\BooleanScorer.cs:第 88 行 在 Lucene.Net.Search.TermScorer.Score(收集器 c,Int32 结束,Int32 firstDocID) 在 d:\Lucene.Net\FullRepo\trunk\src\core\Search\TermScorer.cs:第 80 行
在 Lucene.Net.Search.BooleanScorer.Score(收集器收集器,Int32 最大值,Int32 firstDocID)在 d:\Lucene.Net\FullRepo\trunk\src\core\Search\BooleanScorer.cs:323 行 在 Lucene.Net.Search.BooleanScorer.Score(Collector collector) 中 d:\Lucene.Net\FullRepo\trunk\src\core\Search\BooleanScorer.cs:第 389 行 在 Lucene.Net.Search.IndexSearcher.Search(权重,过滤器 过滤器,收集器收集器)在 d:\Lucene.Net\FullRepo\trunk\src\core\Search\IndexSearcher.cs:line 228 在 Lucene.Net.Search.IndexSearcher.Search(权重,过滤器 过滤器,Int32 nDocs)在 d:\Lucene.Net\FullRepo\trunk\src\core\Search\IndexSearcher.cs:188 行 在 Lucene.Net.Search.Searcher.Search(Query query, Filter filter, Int32 n) 在 d:\Lucene.Net\FullRepo\trunk\src\core\Search\Searcher.cs:line 108 在 Lucene.Net.Search.Searcher.Search(Query query, Int32 n) 中 d:\Lucene.Net\FullRepo\trunk\src\core\Search\Searcher.cs:118行
在...
如果我改用这个查询:
(Description:tasty) (Gtin:000)
我得到了结果。是什么导致顶部查询中的异常? FWIW,这里是相关代码sn-p:
protected virtual IList<Document> GetDocuments(BooleanQuery query, DirectoryInfo indexLocation, string defaultField)
{
var docs = new List<Document>();
using (var dir = new MMapDirectory(indexLocation))
{
using (var searcher = new IndexSearcher(dir))
{
var queryParser = new QueryParser(Constants.LuceneVersion, defaultField, new StandardAnalyzer(Constants.LuceneVersion));
TopDocs result = searcher.Search(query, Constants.MaxHits);
if (result == null) return docs;
foreach (var scoredoc in result.ScoreDocs.OrderByDescending(d => d.Score))
{
docs.Add(searcher.Doc(scoredoc.Doc));
}
return docs;
}
}
}
基于下面的 cmets,这是我当前未编辑但仍然无法工作的代码。
protected virtual IList<Document> GetDocuments(BooleanQuery query, DirectoryInfo indexLocation, string defaultField)
{
var docs = new List<Document>();
using (var dir = new MMapDirectory(indexLocation))
{
using (var searcher = new IndexSearcher(dir))
{
using (var analyzer = new StandardAnalyzer(Constants.LuceneVersion))
{
var queryParser = new QueryParser(Constants.LuceneVersion, defaultField, analyzer);
var collector = TopScoreDocCollector.Create(Constants.MaxHits, true);
var parsed = queryParser.Parse(query.ToString());
searcher.Search(parsed, collector);
var docsresult = new List<string>();
var matches = collector.TopDocs().ScoreDocs;
foreach (var scoredoc in matches.OrderByDescending(d => d.Score))
{
docs.Add(searcher.Doc(scoredoc.Doc));
}
return docs;
}
}
}
}
【问题讨论】:
-
此外,这个查询:+(Description:tasty) +Gtin:000* 在我的 Lucene.NET impl 上没有返回任何命中,而 Luke(正确地)返回 11 个匹配的文档。
-
“Gtin”索引为字符串还是数字字段?
-
Luke 通常会返回“不同”的结果,因为分析器通常与字段的索引方式不同
-
您的示例实际上并未解析查询。它使用传入的 BooleanQuery。
-
任何多部分查询最终都会作为布尔查询。我可以假设您所指的查询是“查询”参数的“ToString()”吗?这个“流利的查询生成器”是什么?我已经使用 Lucene.net 很多年了。除了简单之外,我从来没有与 3rd 方建设者有过很好的经验。我总是最终生成一个查询字符串并解析它,或者很少直接构建查询对象图。除非你能提供一个更完整的例子,有点像我下面的答案,否则很难走得更远。
标签: c# .net lucene full-text-search lucene.net