设为首页 收藏本站
查看: 1113|回复: 0

[经验分享] solr 使用edismax来控制评分

[复制链接]

尚未签到

发表于 2017-12-19 09:39:25 | 显示全部楼层 |阅读模式
如何控制评分
  如果设置了sort字段,那么将会按照sort字段的顺序返回结果。
  如果没有设置sort字段,那么将会根据相关度打分来排序。也就是说,相关度更高的排在前面。
  如何来定制适合自身业务的排序打分规则(boost)呢?经过这段时间的思考与实践,想到了如下三个方法:
  1、定制Lucene的boost算法,加入自己希望的业务规则;
  2、使用Solr的edismax实现的方法,通过bf查询配置来影响boost打分。
  3、在建索引的schema时设置一个字段做排序字段,通过它来影响文档的总体boost打分。
  上面每一种方法都有其优劣,下面分析一下各自的优劣。
  第一种方法技术难度要求较高,需要读懂Lucene的boost打分算法,在代码层做定制.
  第二种方式就简单不少,不过因为受限于edismax提供的方法,所以有些局限性。
  第三种排序可完全消除文本相关性打分的影响,文本检索匹配逻辑只负责打到匹配的项,排序由自定义字段处理。
  下面重点看edismax的使用:
edismax的理念:
  edismax中将查询字段和查询词项分开了,如我们在标准用法中使用name:zjf,那么在edismax中,需要在qf中设置查询字段为name,然后在q中输入zjf,注意这里不能加name了,否则没有结果。
  这样设计的结果就是,查询词项会去所有的qf列(query field,可以设置多列,也可以配置为每列配置权重)上进行查询,如果要针对每个字段有不同的查询,如name:zjf,age:30,那么需要将其中一个移入到fq中,但是注意,fq中的查询是不影响评分的。这也是edismax的理念。满足常用的搜索场景。
edismax的常用参数:
  q和fq来自标准查询,也经常使用。
  edismax扩展的有:
  qf:query field。q中的词项要在哪些字段上执行查询。可以设置多列以及每一列的权重。如果没有设置,那么将会使用df默认字段(一般在配置文件中配置好)。
  pf:parse field。pf和qf的格式一样。区别是pf会更加注重短语匹配,也就是说如果输入zjf xhj作为查询,那么在配置了pf的字段上,zjf随后出现xhj的文档的评分更高。注意这里只是评分更高,如果想获得更加严格的短语匹配,应该在查询中使用"zjf xhj"。
  ps:用于配置pf中的词项的短语间隔。可以控制zjf和xhj之间多少个间隔。
  bq:接受一个和q一样的查询,它和q的区别是不影响返回的结果集,只会影响排名。
  bf:提升函数,通过数学公式来影响评分,而且不局限在qf中的字段。
  mm:最小匹配,如果我们不严格要求AND,可以配置mm来定义查询结果集的匹配程度。
  注意:想pf 和qf这种需要查询的字段上,一定要是indexed的。
关于mm
  mm可以设置为整数,如2,代表至少匹配两个词项,如果输入词项少于两个,那么要全部匹配才行。
  mm可以设为百分比,表示必须匹配到多大的百分比才可以。也可以合并在一起匹配。
  如设置为mm="2<50%" 那么如下查询的话:
  solr: 只有一个词项,必须全部匹配。
  solr is:2个词项,也必须全部匹配。
  solr is a:超过两个,按照50%来计算,只需要匹配一个词项就可以。(一个词项占33%,四舍五入到50%)
  solr is a serch:必须匹配两个,50%。
edismax列子,以下来自网络
  例子1,来自网络。
  下面结合最近使用Solr的实践,着重介绍一下通过使用Solr的DisMaxQParserPlugin通过配置来制定结果文档打分规则。
  DisMaxQParserPlugin提供在针对文本boost打分上,支持搜索多个schema索引字段,并针对每一个字段设置不同的boost权限。
  pf查询 与 qf查询
  pf: 可提供对一条记录的多个字段做匹配的功能
  qf: 针对查询的每个字段设置不同的boost权重打分,其设置的字段必须为在pf中配置的项。
  可在solrconfig.xml中的browse中配置做如下配置:
  <requestHandler name="/browse">
  <lst name="defaults">
  <str name="defType">edismax</str>
  <str name="pf">

  name info>  </str>
  <str name="qf">

  name^1 info^0.8>  </str>
  </lst>
  </requestHandler>
  上面一段的意思是,查询name,info,title三个字段,每个字段的文本相关度打分分别为1,0.8,0.6。计算查询出的每一条结果的权重方法如下:分别计算各字段的文本打分然后乘于配置的系统,最后三者相加即为该结果的boost得分。
  bf查询
  除去pf查询,qf查询之外,仍然希望索引记录的其它字段能够计入打分中,这时可以使用bf查询。bf查询支持一些数据函数,这些函数可作用在索引记录的字段上,多为时间,数值等字段。同样bf也支持添加权重。下面是一个使用bf查询配置的例子:
  <requestHandler name="/browse">
  <lst name="defaults">
  <str name="defType">edismax</str>
  <str name="bf">
  sum(recip(ms(NOW,created_time),3.16e-11,1,1),sqrt(log(max(sales,1))),sqrt(log(count)))^10
  </str>
  <str name="pf">

  name info>  </str>
  <str name="qf">

  name^1 info^0.8>  </str>
  </lst>
  </requestHandler>
  其中sum,recip,ms,sqrt,log,max这些都是Solr提供的数学方法,支持的所有数学方法可在这里查找到:http://wiki.apache.org/solr/FunctionQuery
  edismax相关资源:http://wiki.apache.org/solr/DisMaxQParserPlugin
sum
  Solr1.3 sum(x,y,...) 返回多个函数的和。

  • Example Syntax: sum(x,1)
  • Example Syntax: sum(x,y)
  • Example Syntax: sum(sqrt(x),log(y),z,0.5)
recip
  recip(x,m,a,b)实现a/(m * x + b)的互逆函数。 m,a,b是常数,x是任何数字字段或任意复杂的函数。
  当a和b相等,x> = 0时,该函数的最大值为1,随x增加而下降。将a和b的值增加在一起导致整个功能的移动到曲线的较平坦部分。这些属性可以使这成为在x是rord(datefield)时提升更新文档的理想功能。

  • Example Syntax: recip(rord(creationDate),1,1000,1000)
max
  max(x,c) returns the max of another function and a constant. Useful for "bottoming out" another function at some constant.

  • Example Syntax: max(myfield,0)
log
  Solr1.3 log(x) returns log base 10 of the function x.返回函数x的log10。

  • Example Syntax: log(x)
  • Example Syntax: log(sum(x,100))
sqrt
  Solr1.3 sqrt(x) returns the square root of the function x返回函数x的平方根

  • Example Syntax: sqrt(2)
  • Example Syntax: sqrt(sum(x,100))
  例子2,来自http://www.xuebuyuan.com/323380.html
  举一个例子,电商类网站(比如淘宝)的商品搜索:
  1.在商品名称上出现搜索关键字排序靠前,而内容的次之
  2.对多皇冠的买家排序靠前等
  3.对近期发布的商品排序靠前
  4.对最近销售多商品靠前
  综上获得一个综合排名
  在solrconfig.xml的SearchHandler中如下配置
  Xml代码  

  • <requestHandler name="standard" class="solr.StandardRequestHandler" default="true" >
  •     <lst name="defaults">
  •         <str name="echoParams">explicit</str>
  •         <str name="rows">10</str>
  •         <str name="hl">on</str>
  •         <str name="hl.fl">name,content</str>
  •         <str name="f.content.hl.fragsize">200</str>
  •         <str name="defType">edismax</str>
  •         <str name="bf">
  •             sum(recip(ms(NOW,pub_date),1,1,100),div(point,5632000),div(sale_count,1000000))
  •         </str>
  •         <str name="pf">
  •             content
  •         </str>
  •         <str name="qf">
  •             name^1.9
  •         </str>
  •     </lst>
  • </requestHandler>
div
  Solr1.3 div(x,y) divides the function x by the function y.

  • Example Syntax: div(1,x)
  • Example Syntax: div(sum(x,100),max(y,1))
ms
  Solr1.4
  Returns milliseconds of difference between it's arguments.

  Dates are>  Arguments may be numerically indexed date fields such as TrieDate (recommended field type for dates since Solr 1.4), or date math (examples in SolrQuerySyntax) based on a constant date or NOW.
  Things other than these will _not_ work as arguments. For example, you cannot currently use:

  • "classic", non-numerically indexed date fields (i.e. fields backed by DateField or LegacyDateField classes)
  • other functions (e.g. map, sum, etc.)
  Arguments may _not_ be "classic" date fields
  ms()

  • Equivalent to ms(NOW), number of milliseconds since the epoch.
  ms(a)

  • Returns the number of milliseconds since the epoch that the argument represents.  Example: ms(NOW/DAY)
  • Example: ms(2000-01-01T00:00:00Z)
  • Example: ms(mydatefield)
  Note that this number can be negative for dates from before the epoch.
  ms(a,b)

  • Returns the number of milliseconds that b occurs before a (i.e. a - b). Note that this offers higher precision than sub(a,b) because the arguments are not converted to floating point numbers before subtraction.
  • Example: ms(NOW,mydatefield)
  • Example: ms(mydatefield,2000-01-01T00:00:00Z)
  • Example: ms(datefield1,datefield2)
  bf用函数计算某个字段的权重,如上例子中pub_date发布日期的权重,point比如诚信指数,sale_count销售数量
  bf内字段必须是索引的,bf的函数查看solr api文档 http://wiki.apache.org/solr/FunctionQuery
  pf查询字段,这样在schema不用制定默认字段
  qf对默认查询增加权重比值,比如标题是content的1.9倍,值越大权重越大
  这样查询就会计算如下的一个综合评分值了

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-425609-1-1.html 上篇帖子: 1.solr学习速成之配置文件 下篇帖子: Solr 6.7学习笔记(04)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表