Lucene:完全禁用权重、评分、排名、,

Lucene:完全禁用权重、评分、排名、,,lucene,Lucene,我正在使用Lucene建立一个标记共现的大索引(例如,[大象,动物],[甜瓜,水果],[宝马,汽车],…)。我使用BooleanQuery查询这些共现的索引以获得绝对计数,这两个标记在我的索引中共现的频率如下: // search for documents which contain word+category BooleanQuery query = new BooleanQuery(); query.add(new TermQuery(new Term("word", word)), Oc

我正在使用Lucene建立一个标记共现的大索引(例如,
[大象,动物]
[甜瓜,水果]
[宝马,汽车]
,…)。我使用
BooleanQuery
查询这些共现的索引以获得绝对计数,这两个标记在我的索引中共现的频率如下:

// search for documents which contain word+category
BooleanQuery query = new BooleanQuery();
query.add(new TermQuery(new Term("word", word)), Occur.MUST);
query.add(new TermQuery(new Term("category", category)), Occur.MUST);
// only care about the total number of hits
TotalHitCountCollector collector = new TotalHitCountCollector();
searcher.search(query, collector);
int count = collector.getTotalHits();
这些查询运行非常频繁,我目前对性能不满意。我发现,方法
BooleanQuery#createWeight
需要很多时间。现在,我不需要对我的结果进行任何评分或排名,因为我只对absolut文档计数感兴趣


是否有一种方便的方法(例如预先存在的类别)完全禁用评分和加权?如果没有,是否有任何提示我需要为我的用例扩展哪些类?

我不太确定它是否会以这样的方式绕过评分,从而获得您想要的性能提升,但是应用常量评分的一种简单方法是将查询包装成一个字符串,如:

但是,我强烈建议使用
Filter
s。过滤器不仅会绕过分数,还会缓存结果,因此您的“类别”字段似乎是一个非常好的地方。第一次使用过滤器在类别中查询时,由于需要为该过滤器构建缓存,因此需要花费更长的时间,但是在这之后,您应该会看到速度有了非常显著的提高。请看下面的图片

比如:


我有一个类似的问题,并且提出了这个与Lucene 7兼容的解决方案。(遗憾的是,FieldCacheTermsFilter类和接受筛选器的搜索方法在Lucene 7中不可用)


谢谢你的评论;我尝试了ConstantCoreQuery,但是它似乎将其大部分功能委托给了包装查询,因此我无法通过这种方式实现加速。这个过滤器听起来很有前途,我要试试看!给人印象深刻的使用
FieldCacheTermsFilter
,速度现在感觉像是100倍。非常感谢。
BooleanQuery bq = new BooleanQuery();
//etc.
ConstantScoreQuery query = new ConstantScoreQuery(bq);
searcher.search(query, collector);
Query query = new TermQuery(new Term("word", word));
Filter filter = new FieldCacheTermsFilter("category", category);
TotalHitCountCollector collector = new TotalHitCountCollector();
searcher.search(query, filter, collector);
int count = collector.getTotalHits();
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.SimpleCollector;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class UnscoredCollector extends SimpleCollector {
    private final List<Integer> docIds = new ArrayList<>();
    private LeafReaderContext currentLeafReaderContext;

    @Override
    protected void doSetNextReader(LeafReaderContext context) throws IOException {
        this.currentLeafReaderContext = context;
    }

    @Override
    public boolean needsScores(){
        return false;
    }

    @Override
    public void collect(int localDocId) {
        docIds.add(currentLeafReaderContext.docBase + localDocId);
    }
}
UnscoredCollector collector = new UnscoredCollector();
indexSearcher.search(query, collector);
//docId's are now available in the docIds ArrayList in the UnscoredCollector