在Lucene查询中过滤少于N个术语的文档

时间:2012-12-17 10:08:10

标签: lucene

作为Lucene查询的一部分,是否可以从结果文件中排除少于N个术语或小于给定大小的文档?

完整的故事:我有一个包含许多文档的Lucene索引。其中一些很大,另一些很小,可能只有几个字。我想运行一些测试,但仅限于合理大小的文档。如何过滤掉小文件?目前,我正在获取术语频率向量和删除少于N个术语的文档:

BooleanQuery q = some query...
TopDocs top = indexSearcher.search(q, size);
Collection<Integer> docNums = collectDocNums(top);
Iterator<Integer> it = docNums.iterator();
while (it.hasNext()) {
  int candDocNum = it.next();
  TermFreqVector tfv =
    indexReader.getTermFreqVector(candDocNum, "field");
  if (tfv.getTerms().length < N)
     it.remove();
}

这可以通过在查询本身中进行过滤,或以某种方式对其下面的循环进行批处理来更有效地完成吗?

2 个答案:

答案 0 :(得分:1)

过滤器可能是合理的实现。听起来这样的过滤器在搜索时会经常重复使用,因此缓存过滤器是值得的。我不知道有任何标准的过滤器可以实现这一点,但是自定义过滤器可以很好地工作。

我实现了类似的东西:

//Important to wrap the filter with a CachingWrapper, for performance.
filter = new CachingWrapperFilter(new CustomFilter());

public class CustomFilter() Extends Filter{
    public getDocIdSet(IndexReader reader) {
        return new CustomSet(reader);
    }
}

public class CustomSet(IndexReader reader) extends FilteredDocIdSet{
    public boolean match(int docid) {
        reader.getTermFreqVector(candDocNum, "field");
        return (tfv.getTerms().length >= N);
    }
}

答案 1 :(得分:0)

查看PositiveScoresOnlyCollector:它只会收集score > 0的文档。您可以编写自己的类似收集器,只接受具有score > X的文档。

上述内容当然只适用于NX之间的某种关系。根据我的理解,这两件事应该相关:匹配条款越少,分数越小,反之亦然。

如果您可以定义一些最低分数阈值,这种方法应该比您当前使用的方法更有效。