我希望能够统计Lucene中某个字段上术语的文档数量。我知道3种方法做到这一点,我想知道最好和最快的实践方法是什么:
我将在一个长类型单值字段("field")中搜索该术语(所以不是文本,而是数字化数据!)
以下任何示例代码都将首先使用:
Directory dirIndex = FSDirectory.open('/path/to/index/');
IndexReader indexReader = DirectoryReader.open(dirIndex);
final BytesRefBuilder bytes = new BytesRefBuilder();
NumericUtils.longToPrefixCoded(Long.valueOf(longTerm).longValue(),0,bytes);
1) 使用 Index 中的 docFreq()
TermsEnum termEnum = MultiFields.getTerms(indexReader, "field").iterator(null);
termEnum.seekExact(bytes.toBytesRef());
int count = termEnum.docFreq();
2) 搜索它
IndexSearcher searcher = new IndexSearcher(indexReader);
TermQuery query = new TermQuery(new Term("field", bytes.toBytesRef()));
TotalHitCountCollector collector = new TotalHitCountCollector();
searcher.search(query,collector);
int count = collector.getTotalHits();
3)从索引中读取精确匹配的内容,并逐个计算文档数
TermsEnum termEnum = MultiFields.getTerms(indexReader, "field").iterator(null);
termEnum.seekExact(bytes.toBytesRef());
Bits liveDocs = MultiFields.getLiveDocs(indexReader);
DocsEnum docsEnum = termEnum.docs(liveDocs, null);
int count = 0;
if (docsEnum != null) {
int docx;
while ((docx = docsEnum.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
count++;
}
}
最佳方法
选项1)代码最短,但是如果您更新和删除索引中的文档,它基本上是无用的。它将已删除的文档计算为仍在那里。没有在很多地方记录(除了官方文档外,在这里的答案中没有)。需要注意的事项。也许有一种方法可以避免这种情况,否则对此方法的热情有点过热。 选项2)和3)产生正确的结果,但哪个更好?或者更好的是 - 有没有更快的方法来做到这一点?