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