0
回答
Lucene6.6 添加因子影响文档打分
开发十年,就只剩下这套Java开发体系了   

需求描述:

我想添加一个可以改变文档打分的因素,以便可以灵活调整搜索结果。

注:在Lucene6.6 版本的上 Document.setBoost 方法已经被删除。

 

通过阅读 文档 和 Lucene原理和代码解析(这是早期版本的) 其中相关部分,

我尝试了调整 Similarity ,但发现其暴露的接口修改起来还是太复杂了,通读其中涉及的源码还要消耗大量的精力,所以最终放弃了这个方式。

最后选择了重写 TopDocsCollector 的方式,虽然目的是达到了,但是多了很多代码,变得很不优雅,不知道大家是怎么做的,希望可以分享一下。

我目前的实现思路:

构建索引时为每个文档增加一个打分因子的Field:

doc.add(new NumericDocValuesField("score", score));

搜索调用这个接口:

IndexSearcher.search(Query query, CollectorManager<C, T> collectorManager)

重写CollectorManager,在newCollector()方法返回重写TopDocsCollector,大概如下,实际还有很多多余的代码,都是复制IndexSearcher里面的实现。

private static class SimpleTopScoreDocCollector extends TopScoreDocCollector {

            SimpleTopScoreDocCollector(int numHits) {
                super(numHits);
            }

            @Override
            public LeafCollector getLeafCollector(LeafReaderContext context)
                    throws IOException {
                final int docBase = context.docBase;
                return new ScorerLeafCollector() {

                    @Override
                    public void collect(int doc) throws IOException {
                        float score = scorer.score();

                        NumericDocValues scoreDocValues = context.reader().getNumericDocValues("score");

                        if(scoreDocValues != null){
                            long factor = scoreDocValues.get(doc); //其实就为了增加这一句,多了n多代码~
                            score = score * factor; //假设相乘
                        }

                        // This collector cannot handle these scores:
                        assert score != Float.NEGATIVE_INFINITY;
                        assert !Float.isNaN(score);

                        totalHits++;
                        if (score <= pqTop.score) {
                            // Since docs are returned in-order (i.e., increasing doc Id), a document
                            // with equal score to pqTop.score cannot compete since HitQueue favors
                            // documents with lower doc Ids. Therefore reject those docs too.
                            return;
                        }
                        pqTop.doc = doc + docBase;
                        pqTop.score = score;
                        pqTop = pq.updateTop();
                    }

                };
            }

        }

 

<无标签>
举报
叶大侠
发帖于6个月前 0回/172阅
顶部