我正在更新一个使用 Lucene 索引的工具。作为此更新的一部分,我们将从 Lucene 2.0.0 迁移到 3.0.2。在大多数情况下,这完全是简单的。然而,在一个例子中,我似乎无法找到一种简单的转换。
基本上我有一个简单的查询,我需要迭代所有命中。在 Lucene 2 中这很简单,例如:
Hits hits = indexSearcher.search(query);
for(int i=0 ; i<hits.length() ; i++){
// Process hit
}
在 Lucene 3 中,IndexSearcher
的 API 发生了显着变化,尽管我可以将一些有效的东西组合在一起,但这只能通过获取顶级 X
文档并确保X
足够大。
虽然点击次数(在我的例子中)通常在零到十之间,但也存在异常情况,点击次数可能会更高。因此有一个固定的限制感觉是错误的。此外,将限制设置得非常高会导致 OOME,这意味着立即为所有 X
可能的命中分配空间。由于此操作执行很多,因此需要相当高效的操作。
编辑:
目前我有以下工作要做:
TopDocs hits = indexSearcher.search(query, MAX_HITS);
for (int i=0 ; i<hits.totalHits ; i++) {
// Process hit
}
这工作正常,除了
a)如果点击次数多于MAX_HITS
怎么办?
和
b) 如果 MAX_HITS 很大,那么我就会浪费内存,因为在执行搜索之前为每个命中分配了空间。
由于大多数时候只会出现几次点击,我不介意进行后续搜索以获得后续点击,但我似乎无法找到一种方法来做到这一点。
最佳答案
IndexSearcher 有一个方法docFreq(Term)
。调用它似乎不会造成性能损失,并且它的输出是要获取的文档数量的合适输入参数。
例如
int freq = searcher.docFreq(new Term(FIELD, value));
TopDocs hits = indexSearcher.search(query, freq);
for (int i=0 ; i<hits.totalHits ; i++) {
// Process hit
}
这是有效的,因为我的查询本质上是一个 TermQuery
。如果它是一个更复杂的查询,那么这将不合适。
关于java - Lucene 3 迭代所有命中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3300265/