solr 4.2 使用插件链来完善、简化增量index逻辑

来源:互联网 发布:淘宝靠谱日代推荐 编辑:程序博客网 时间:2024/05/21 10:59

业务背景


之前做村淘的时候开发过一个插件,即动态的根据商品的类目判定该商品是不是要被和谐,所以了解到在update商品信息的时候,商品是肯定会经过一个由若干Processor组成的chain最终进入底层索引的

现在遇到的问题是这样的,当前的商品逻辑比较复杂,有很多不是从db里得到的字段,进索引时会根据业务逻辑做相应的处理,例如时间间隔,title,以及离线的一些分数,例如商品预测质量分等。全量索引时逻辑是完全可控,但是增量的索引如果默认使用小白版本的update方式就会导致后台的web端逻辑承载了太多的搜索引擎相关的逻辑,很重,而且每次业务逻辑有过改动以后,都需要把相同的逻辑java端写一份,web端写一份,然后code review,不出意外的话也是经常出错。。所以痛定思痛决定开发solr的update插件来从根本上解决增量的问题,把web端同志解救出来。

UpdateRequestProcessorChain
默认的chain是由

  • LogUpdateProcessorFactory
  • DistributedUpdateProcessorFactory
  • RunUpdateProcessorFactory

构成的,而根据solr官方文档解释,DistributedUpdateProcessorFactory是默认在RunUpdateProcessorFactory的前面出现的,这是为了支持solrcloud的功能。

Begining with Solr4.0 all UpdateRequestProcessorChains which include RunUpdateProcessorFactory, but do not include an implementation of the DistributingUpdateProcessorFactory will have an instance of DistributedUpdateProcessorFactory automaticly injected immediately prior to the RunUpdateProcessorFactory.

所以即使我业务上配置的updateRequestProcessorChain并没有显示的DistributedUpdateProcessorFactory,而在实际代码执行的时候也会把DistributedUpdateProcessorFactory放置在RunUpdateProcessorFactory前,于是在使用mychain来update文档的时候,也会构造出来一个有4个ProcessorFactory的chain用于进行处理。而至于softCommit等相关配置只与最终的UpdateHandler相关,即RunUpdateProcessorFactory会调用UpdateHandler来进行commit等相关操作,所以新的chain不会影响softCommit等相关配置。

<updateRequestProcessorChain name="mychain" >     <processor class="com.niuniu.update.plugin.NiuniuProcessorFactory" />     <processor class="solr.LogUpdateProcessorFactory" />     <processor class="solr.RunUpdateProcessorFactory" />   </updateRequestProcessorChain> 

那么要如何配置我们自定制的updateRequestProcessorChain要先了解一下solr.LogUpdateProcessorFactory、DistributedUpdateProcessorFactory以及solr.RunUpdateProcessorFactory对应的是什么功能,然后就知道自己应该把定制化的ProcessorFactory放在chain的哪一块。

  • LogUpdateProcessorFactory是用来打log的
  • RunUpdateProcessorFactory是用来把更新的内容持久化到磁盘的

所以我们的业务相关的ProcessorFactory应该在chain的最顶端,也即官方文档说的:

Configuring Individual Processors as Top-Level Plugins

参考官方的定制化ProcessorFactory开发文档:

package my.solr;import java.io.IOException;import org.apache.solr.common.SolrInputDocument;import org.apache.solr.request.SolrQueryRequest;import org.apache.solr.response.SolrQueryResponse;import org.apache.solr.update.AddUpdateCommand;import org.apache.solr.update.processor.UpdateRequestProcessor;import org.apache.solr.update.processor.UpdateRequestProcessorFactory;public class ConditionalCopyProcessorFactory extends UpdateRequestProcessorFactory{  @Override  public UpdateRequestProcessor getInstance(SolrQueryRequest req, SolrQueryResponse rsp, UpdateRequestProcessor next)  {    return new ConditionalCopyProcessor(next);  }}class ConditionalCopyProcessor extends UpdateRequestProcessor{  public ConditionalCopyProcessor( UpdateRequestProcessor next) {    super( next );  }  @Override  public void processAdd(AddUpdateCommand cmd) throws IOException {    SolrInputDocument doc = cmd.getSolrInputDocument();    Object v = doc.getFieldValue( "popularity" );    if( v != null ) {      int pop = Integer.parseInt( v.toString() );      if( pop > 5 ) {        doc.addField( "cat", "popular" );      }    }    // pass it up the chain    super.processAdd(cmd);  }}  

部署完成以后,就可以在增量更新(add or update)的时候指定好update.chain=mychain就可以满足我们的业务需求了

curl "http://localhost:8983/solr/production/update?update.chain=mychain" -H "Content-Type: text/xml" --data-binary '<add><doc>    <field name="id">10</field>    <field name="brand_name">福特</field>    <field name="car_model_name">野马</field>    <field name="standard_name">中规</field>    <field name="remark">康桑密达</field>  </doc>  </add>'

目前中文的文档较少特此记录。

参考

Solr Confluence
Solr Wiki

0 0
原创粉丝点击