我知道有可能在Lucene索引中获得最高项,但是有没有办法根据Lucene索引的子集获得最高项?
即在特定日期范围内的文档索引中的最高术语是什么?
理想情况下,某个地方有一个实用工具,但我不知道.然而,以合理有效的方式"手动"完成这项工作并不困难.我假设您已经有一个Query
和/或Filter
对象可用于定义感兴趣的子集.
首先,在内存中构建索引子集中所有文档ID的列表.您可以IndexSearcher.search(Query, Filter, HitCollector)
非常快速地使用它; 该HitCollector
文件包含好像它应该工作,或者你可以使用一些其他的容器来存储您的文档ID的例子.
接下来,初始化一个空的HashMap(或其他)以将术语映射到总频率,并通过IndexReader.getTermFreqVector
为每个感兴趣的文档和字段调用其中一种方法来填充地图.三参数形式似乎更简单,但要么两者都应该没问题.对于三参数形式,您将使用TermVectorMapper
其map
方法检查是否term
在地图中,frequency
如果不在,则将其关联,或者如果是,则添加frequency
到现有值.确保在此过程中的TermVectorMapper
所有调用中使用相同的对象getTermFreqVector
,而不是为循环中的每个文档实例化一个新对象.您也可以通过重写加快速度相当多的isIgnoringPositions()
和isIgnoringOffsets()
; 你的对象应该返回true
两者.它看起来像你的TermVectorMapper
也可能被迫定义一个setExpectations
方法,但那个方法不需要做任何事情.
构建地图后,只需按降序频率对地图项进行排序,然后读出您喜欢的许多顶级术语.如果您事先知道您想要多少个术语,您可能更喜欢使用某种基于堆的算法来查找线性时间中的前k个项而不是使用O(n log n)排序.我想,在实践中,这种简单的老式会很快.但这取决于你.
如果您愿意,可以通过直接HitCollector
调用来组合前两个阶段getTermFreqVector
.这当然应该产生同样正确的结果,并且直观地看起来它会更简单和更好,但是文档似乎警告说这样做可能比两遍方法慢得多(与HitCollector示例在同一页面上)以上).或者我可能会误解他们的警告.如果你有野心,你可以尝试两种方式,比较,让我们知道.