lucene 自定义评分 影响排序

寵の児 提交于 2020-04-15 23:27:10

【推荐阅读】微服务还能火多久?>>>

前记

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

为什么要去修改呢,当然是搜索结果不太令人满意啦,于是去研读了项目中关于搜索的代码。。。。。。


正文

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

  1. 创建索引的过程,相当简单,感觉仅仅是把lucene当成关键词匹配的工具去了(需要修改索引策略)

  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去搜索。。。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!