lucene 自定义评分 影响排序

前记apache

这段时间须要修改一个别人写的一个搜索有关的项目,刚好底层使用的是lucene搜索框架。框架

为何要去修改呢,固然是搜索结果不太使人满意啦,因而去研读了项目中关于搜索的代码。。。。。。ide


正文工具

通过了几天代码的研读,最终总结出来了几条问题:this

  1. 建立索引的过程,至关简单,感受仅仅是把lucene当成关键词匹配的工具去了(须要修改索引策略)spa

  2. 搜索的过程也是比较简单,没有结合项目的需求,定制化搜索(搜索策略须要修改)对象

  额,感受上面两条好像是在说废话,感受lucene的和核心就是索引和搜索排序

为了能尽快解决问题,初步修改就定为了:继承

  1. 索引阶段,将信息分红多个域,同时根据域的重要程度,加入权重。还有就是加入搜索结果排序要使用的字段(分域,权重,加入排序字段)索引

  2. 搜索阶段 根据类别搜索不一样的域,同时加入自定义评分

下面就简单的说一下自定义评分:

我用的是lucene是:

<dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-core</artifactId>
            <version>4.10.2</version>
</dependency>

上网查了不少的资料,发现lucene实现自定义评分是经过在构建查询的时候加入的,操做起来很方便。直接上代码吧:

public class MyCustomScoreQuery extends CustomScoreQuery {
    public MyCustomScoreQuery(Query subQuery) {
        super(subQuery);
    }

    @Override
    protected CustomScoreProvider getCustomScoreProvider(
            AtomicReaderContext context) throws IOException {
        /**
         * 自定义的评分provider
         * **/
        return new AbilityCoverageScoreProvider(context);
    }

    private class MyCustomScoreProvider extends CustomScoreProvider {
        private AtomicReaderContext context = null;

        public MyCustomScoreProvider(AtomicReaderContext context) {
            super(context);
            this.context = context;
        }

        @Override
        public float customScore(int doc, float subQueryScore, float valSrcScore)
                throws IOException {
            //获取double型,使用Cache获取更加的快速
            FieldCache.Doubles doubles = FieldCache.DEFAULT.getDoubles(context.reader(), "range", false);
            double range= doubles.get(doc);
            
            return subQueryScore + range;
        }

    }

}

总结下来就是:

继承CustomScoreQuery类,覆盖getCustomScoreProvider(AtomicReaderContext context)方法,返回本身的评分对象

继承CustomScoreProvider,覆盖customScore(int doc, float subQueryScore, float valSrcScore)方法,返回评分结果

自定义评分逻辑就是写在customScore(int doc, float subQueryScore, float valSrcScore)里面,事先算好的排序因子,能够当成是域放在document里面,而后在自定义评分的时候取出来,实现自定义评分从而影响排序。

 

最后就只用使用本身的MyCustomScoreQuery去包装一个query,而后去搜索就好了。

Query query = 生成好的query

Query customQuery = new MyCustomScoreQuery(query);

最后用customQuery去搜索。。。

相关文章
相关标签/搜索