solr 竞价排名


借助solr 的QueryElevationComponent实现竞价排名,相关的wiki如下:

http://wiki.apache.org/solr/QueryElevationComponent


相关配置:

在$solr_home/data/目录或者在$solr_home/conf/目录下加入文件elevate.xml, 内容如下

<?xml version="1.0" encoding="UTF-8" ?>
<elevate>
 <query text="hello">
  <doc id="4" />
 </query>
</elevate>

然后配置下solrconfig.xml

   <searchComponent name="elevator" class="solr.QueryElevationComponent" >
    <!-- pick a fieldType to analyze queries -->
    <str name="queryFieldType">string</str>
    <str name="config-file">elevate.xml</str>
  </searchComponent>


 <requestHandler name="standard" class="solr.SearchHandler" default="true">
     <lst name="defaults">
       <str name="echoParams">explicit</str>
       <str name="rows">10</str>
       <str name="fl">*,score</str>
     </lst>
	 
    <arr name="last-components">
      <str>elevator</str>
    </arr>
	 
  </requestHandler>  

有两个重要的参数作为启动竞价排名组件:enableElevation=true&forceElevation=true

enableElevation=true:启动 elevator,默认为false

forceElevation=true:强制性使用竞价排名优先,当使用例如sort=id desc ,则默认为不破坏该排序,如果加了该 参数forceElevation=true则为强制使用竞价优先原则,否则相反


example:请求URL如下

http://localhost:38080/searchTest/core0/select/?q=hello&sort=key%20desc&enableElevation=true&debugQuery=on&forceElevation=true


由于solr3.5中的QueryElevationComponent 还是要求唯一值要使用StrField类型,如果不使用则会抛出如下 异常:

QueryElevationComponent requires the schema to have a uniqueKeyField implemented using StrField


当然很多时候我们的唯一值是数值类型,刚好看到正在开发的solr版本已支持其它类型,但现在也没有发布,所以也只能由自己来hack了。。


https://issues.apache.org/jira/browse/SOLR-1520


还有一个不满的就是QueryElevationComponent 还不支持分布式,看来也得自己来实现 了




solr实现竞价排名的思路大概如下:


1)该组件会在每次reader变化时加载竞价排名的配置,将关键对应的文档建成一个map

2)搜索的时候增加一个booleanQuery,将原来的query加入,并加入一个命中竞价排名关键词所对应的ids,变成一个query加入这个booleanQuery,这样就可以搜索出竞价对应的文档

3)修改排序,新增一个sort作为第一排序字段,而这个字段只有命中竞价的文档才有分值,否则都为0,这样就可优先竞价的文档


else {
        BooleanQuery newq = new BooleanQuery( true );
        newq.add( query, BooleanClause.Occur.SHOULD );
        newq.add( booster.include, BooleanClause.Occur.SHOULD );
        if( booster.exclude != null ) {
          for( BooleanClause bq : booster.exclude ) {
            newq.add( bq );
          }
        }
        rb.setQuery( newq );
      }


  
      // if the sort is 'score desc' use a custom sorting method to 
      // insert documents in their proper place 
     
      SortSpec sortSpec = rb.getSortSpec();
      if( sortSpec.getSort() == null ) {
        sortSpec.setSort( new Sort( new SortField[] {
            new SortField(idField, booster.comparatorSource, false ),
            new SortField(null, SortField.SCORE, false)
        }));
      }
      else {
        // Check if the sort is based on score
        boolean modify = false;
        SortField[] current = sortSpec.getSort().getSort();
        ArrayList<SortField> sorts = new ArrayList<SortField>( current.length + 1 );
        // Perhaps force it to always sort by score
        if( force && current[0].getType() != SortField.SCORE ) {
          sorts.add( new SortField(idField, booster.comparatorSource, false ) );
          modify = true;
        }
        for( SortField sf : current ) {
          if( sf.getType() == SortField.SCORE ) {
            sorts.add( new SortField(idField, booster.comparatorSource, sf.getReverse() ) );
            modify = true;
          }
          sorts.add( sf );
        }
        if( modify ) {
          sortSpec.setSort( new Sort( sorts.toArray( new SortField[sorts.size()] ) ) );
        }
      }
    }













  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值