基于solr定制干预性竞价排名
此文是总结近期搜索项目涉及到竞价排名开发中的一些经验:
- fq和elevate相冲突的问题和解决办法
- 外部条件影响score打分的情况下如何保证title完全吻合的document排名第一
fq和elevate相冲突的问题和解决办法
solr自带实现竞价排名的方案:
如想实现检索手机百度
时id为472885640,100027899,100021742,100001057,100005069,100024808
的这些应用排名靠前,如下即可:
http://192.168.78.39:8080/solr/applist/elevate?start=0&rows=10&q=手机百度&df=title&elevateIds=472885640,100027899,100021742,100001057,100005069,100024808
得到结果:
<response><lst name="responseHeader"><int name="status">0</int><int name="QTime">21</int><lst name="params"><str name="q">手机百度</str><str name="df">title</str><str name="fl">title,score</str><str name="start">0</str><str name="elevateIds">472885640,100027899,100021742</str><str name="rows">10</str></lst></lst><result name="response" numFound="334" start="0" maxScore="6.5899296"><doc><str name="title">JJ斗地主</str><float name="score">0.0</float></doc><doc><str name="title">欢乐斗地主</str><float name="score">0.0</float></doc><doc><str name="title">途游斗地主</str><float name="score">0.0</float></doc><doc><str name="title">手机百度</str><float name="score">6.5899296</float></doc><doc><str name="title">百度手机卫士(百度卫士)</str><float name="score">5.2719436</float></doc><doc><str name="title">百度文库HD</str><float name="score">1.936549</float></doc><doc><str name="title">百度天眼</str><float name="score">1.936549</float></doc><doc><str name="title">百度文库</str><float name="score">1.936549</float></doc><doc><str name="title">百度滴答</str><float name="score">1.936549</float></doc><doc><str name="title">百度外卖</str><float name="score">1.936549</float></doc></result></response>
但是如果搜索的时候加入了其他限制条件(这在实际应用中简直是一定的,比如在制定的分类下,制定的状态下搜索),则上述方法失效:
http://192.168.78.39:8080/solr/applist/elevate?start=0&rows=10&q=手机百度&df=title&elevateIds=472885640,100027899,100021742&fl=title,first_class_id,second_class_id,score&fq=first_class_id:1010000&fq=second_class_id:10105008
得到结果:
<response><lst name="responseHeader"><int name="status">0</int><int name="QTime">32</int><lst name="params"><str name="q">手机百度</str><str name="df">title</str><str name="fl">title,first_class_id,second_class_id,score</str><str name="start">0</str><str name="elevateIds">472885640,100027899,100021742</str><arr name="fq"><str>first_class_id:1010000</str><str>second_class_id:1010500</str></arr><str name="rows">10</str></lst></lst><result name="response" numFound="3" start="0" maxScore="1.936549"><doc><str name="title">百度贴吧HD</str><int name="first_class_id">1010000</int><int name="second_class_id">1010500</int><float name="score">1.936549</float></doc><doc><str name="title">百度贴吧</str><int name="first_class_id">1010000</int><int name="second_class_id">1010500</int><float name="score">1.936549</float></doc><doc><str name="title">百度美秀</str><int name="first_class_id">1010000</int><int name="second_class_id">1010500</int><float name="score">1.936549</float></doc></result></response>
可见,想要加入竞价排名的几个document无法检索到。翻阅solr文档,可以得到原因:
The fq Parameter Query elevation respects the standard filter query (fq) parameter. That is, if the query contains the fq parameter , all results will be within that filter even if elevate.xml adds other documents to the result set.
fq限制了检索范围,elevate只能在范围之内生效。
解决方案是,先直接检索竞价排名的几个document,再检索在限制条件下排除掉这几个竞价排名的document,两次检索结果进行合并:
start=0&rows=20&q=*:*&fl=title,score,first_class_id,second_class_id,title,itunesid,score&qt=/get&ids=472885640,100027899,100021742
,
sort=weight desc,downloadnum desc&start=0&rows=11&q=*&df=title&fq=first_class_id:1010000&fq=second_class_id:1010500&fl=title,score,first_class_id,second_class_id,title,itunesid,score&forceElevation=true&excludeIds=472885640,100027899,100021742&facet=false&qt=/elevate
外部条件影响score打分的情况下如何保证title完全吻合的document排名第一
在外部条件影响score打分的情况下,比如自定义了edixmax,加入下载量或者其他变量,导致title完全吻合但下载量比较低的document无法排名靠前。解决方案类似上面处理竞价排名:
1,新建一个field,复制title的内容,但不进行分词;
2,第一次检索,指定fq:title名称,检索到title完全吻合的document,取得id,拼接成elevateIds;
3,第二次检索,排除掉拼接成elevateIds;
4,两次检索结果合并,方法类似上面处理竞价排名
最后:这里有一个旨在替换掉tomcat+spring+mybatis的基于netty,支持ioc,router,aop,ddd,restful的极简后端框架: https://github.com/rongjoker/quarantineJ ,.欢迎star和fork,相信会对你做java开发、并发编程、网络编程有非常大的帮助.