在搭建好solrCloud搜索集群后,通过编写基本的查询显示语句已经能够通过输入关键字查询到相应结果进行显示,但是在显示结果排序上以及不相关信息过滤问题上,如何制定合理的打分规则得到理想的结果集确实比较麻烦的。Solr本身的排序打分规则是继承自Lucene的文本相关度的打分即boost,这一套算法对于通用的提供全文检索的服务来讲,已经够用了,但是想要根据实际业务需求定制自己的打分机制来获取理想的查询结果,文本相关度的打分是远远不够的。
如何来定制实际业务需求的的排序打分规则(boost)呢?经过调研学习,得到如下三个方法:
1、熟悉Lucene的打分规则算法,根据自己实际业务需求对其源码进行修改来定制自己的一套打分算法。这个对于一般新手来说难度较大,并且研读Lucene底层源码耗费时间较多,并且自己修改的源码的健壮性不能保证(大牛除外),所以对于源码级的功能修改一般不要进行。
2、利用solr自己的排序方法,可以在查询时指定按照哪一字段进行排序,比如按照时间的倒叙等,配置多个字段权重可以通过Solr的edismax实现的方法,配置不同字段的权重最终影响boost的打分。这种方法比较简单,需要配置一下即可用,但有自身的局限性,对于特殊需求达不到满足,比如付费的信息最前显示。
3、在edismax方法的基础上进行修改,edismax支持boost函数与score相乘作为打分结果,可以在建立索引时单独建立一个字段作为排序的依据字段,并且配合其他字段设置权重来共同影响最终的打分结果。这种方法技能满足特殊需求又能够满足文本本身的相关度,是比较理想的一种解决方案。
solr的DisMaxQParserPlugin通过配置来制定结果文档打分规则,提供在针对文本boost打分上,支持搜索多个schema索引字段,并针对每一个字段设置不同的boost权限。
简单的字段权重设置为:
pf: 可提供对一条记录的多个字段做匹配的功能
qf: 针对查询的每个字段设置不同的boost权重打分,其设置的字段必须为在pf中配置的项。
三个查询字段文本的相关度分别为0.8、1、0.6,计算返回结果的方法是各个字段的文本打分乘以权重再相加作为boost得分。
单独设置打分字段的设置为:
bf查询支持一些solr的查询函数,这些函数可以作用在索引的字段上,bf也支持添加权重。
其中vip是为排序单独设置的一个索引字段,date是每条数据发布的时间。
linear(x,m,c)表示 m*x+c ,其中m和c都是常量,x是一个变量也可以是一个函数, sqrt(x) 返回 一个数的平方根,sum(x,y)求两个的和,更多的关于solr的functionquery可以参考:
https://cwiki.apache.org/confluence/display/solr/Function+Queries
edismax的资料可以参考:
https://cwiki.apache.org/confluence/display/solr/Query+Syntax+and+Parsing
vip在数据库中需要根据需要设置为true或者false,
在bf查询时,如果一条记录的vip为true,那么它的分数就会是+1000,类似于竞价排名。
为了过滤不相关的查询结果,一般搜索默认的操作为AND,在managed-schema中设置:
这样在搜索时显示的结果vip信息排在最前面,其他按照设置的权重进行排序: