如何使用HitCollector按字段值对Lucene结果进行排序?

16

我正在使用以下代码在Lucene.Net中执行查询

var collector = new GroupingHitCollector(searcher.GetIndexReader());
searcher.Search(myQuery, collector);
resultsCount = collector.Hits.Count;

如何基于字段对这些搜索结果进行排序?


更新

感谢您的回答。我尝试使用TopFieldDocCollector,但是当我将numHits参数值设置为5000时,出现错误提示"value is too small or too large"。请建议一个有效的值。

4个回答

25

search.Searcher.search 方法可以接受一个 search.Sort 参数,可以简单地构造如下:

new Sort("my_sort_field")

然而,排序的字段有一些限制 - 它们需要被索引但不能被分词,并且值可以转换为StringFloatInteger

《Lucene实战》详细介绍了所有细节,包括按多个字段排序等等。


7
没有进行分词处理,你比我先做到了 :) - James Brady
根据Lucene的文档,存储值并非必需,只需要索引即可。@janwen - Scott Simontis

0

只接受字符串字段名称的 Sort 构造函数已被弃用。现在您需要创建一个排序对象,并将其作为 searcher.Search() 的最后一个参数传入。

/* sorting by a field of type long called "size" from greatest -> smallest 
(signified by passing in true for the last isReversed paramater)*/

Sort sorter = new Sorter(new SortField("size", SortField.Type.LONG, true))
searcher.Search(myQuery, collector, sorter);

0
你需要的可能是TopFieldDocCollector。使用它来代替GroupingHitCollector(那是什么?)或在其内部使用。
如果需要更多信息,请在评论中提出。我很乐意帮助你。

谢谢你的回答……我已经尝试使用 TopFieldDocCollector,但是当我将 5000 作为 numHits 参数值传递时,出现了“值太小或太大”的错误……请建议一个有效的值来传递…… - Ed.

0
在Lucene的原始(Java)版本中,TopFieldDocCollector结果的大小没有硬性限制。任何大于零的数字都可以接受。尽管存在内存约束和性能下降,这会依赖于您的环境,但5000个命中是微不足道的,并且不应该在移动设备之外造成问题。
也许在移植Lucene时,TopFieldDocCollector被修改为使用除了Lucene的“堆”实现(称为PriorityQueue,由FieldSortedHitQueue扩展)之外的其他东西 - 这可能对结果大小施加了一个不合理地小的限制。如果是这样的话,您可能想查看TopFieldDocCollector的源代码,并使用更好的堆实现来实现自己类似的命中收集器。
然而,我必须问一下,为什么要收集5000个结果呢?在交互式应用程序中,没有用户会想要看那么多结果。我认为愿意查看200个结果的用户很少见,但将其加倍到400个只是作为安全因素。根据应用程序的不同,限制结果大小还可以阻碍恶意屏幕抓取程序,并减轻拒绝服务攻击。

1
“在交互应用程序中,没有用户想要看到那么多”有点傲慢。即使出于合法的技术原因我们将其截断为200,000,用户仍会尖叫和抱怨... - Hakanai

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