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

[经验分享] Solr Update插件自定义Update Chain按条件更新索引

[复制链接]

尚未签到

发表于 2017-12-19 11:39:51 | 显示全部楼层 |阅读模式
  背景:基于call客,来电和跟进记录等多个数据来源的用户文档,需要在更新是判断首来源的时间。
  如对电话号码11xxxx来说,来电时间是今天,call客时间是昨天,而call客数据又可能因为网络原因晚上传上来,这样一来11xxxx这个用户document的来源时间需要更新成昨天。
  分析:solr的默认update没有办法匹配业务的灵活的更新逻辑。更新逻辑如下,当更新来源时间的时候,如果新的来源时间比之前的来源时间晚,则保持之前的来源时间。
  代码实现:
  

package custom.solr;  

import java.io.IOException;  

import org.apache.lucene.util.BytesRef;  

import org.apache.solr.common.SolrInputDocument;  

import org.apache.solr.core.SolrCore;  

import org.apache.solr.handler.component.RealTimeGetComponent;  

import org.apache.solr.request.SolrQueryRequest;  

import org.apache.solr.response.SolrQueryResponse;  

import org.apache.solr.search.SolrIndexSearcher;  

import org.apache.solr.update.AddUpdateCommand;  

import org.apache.solr.update.processor.UpdateRequestProcessor;  

import org.apache.solr.update.processor.UpdateRequestProcessorFactory;  

import org.apache.solr.util.RefCounted;  

  

public>
{  
@Override
  

public UpdateRequestProcessor getInstance(SolrQueryRequest req, SolrQueryResponse rsp, UpdateRequestProcessor next)  
{
  

return new ConditionalUpdateProcessor(req, rsp, next);  
}
  
}
  

  

class ConditionalUpdateProcessor extends UpdateRequestProcessor  
{
  

public static final String ORIGIN_TIMESTAMP = "origin_timestamp";  

public ConditionalUpdateProcessor(SolrQueryRequest req, SolrQueryResponse rsp, UpdateRequestProcessor next)  
{
  

super(next);  
core
= req.getCore();  
}
  

  

private final SolrCore core;  

  
@Override
  

public void processAdd(AddUpdateCommand cmd) throws IOException  
{
  
SolrInputDocument newDoc
= cmd.getSolrInputDocument();  
BytesRef indexedId
= cmd.getIndexedId();  
RefCounted
<SolrIndexSearcher> newestSearcher = core.getRealtimeSearcher();  
SolrIndexSearcher searcher;
  

long lookup;  
searcher
= (SolrIndexSearcher) newestSearcher.get();  
lookup
= searcher.lookupId(indexedId);  

//if not exists  
if (lookup < 0)
  
{super.processAdd(cmd);
  
}
  
        SolrInputDocument oldDoc = RealTimeGetComponent.getInputDocument(core, indexedId);
  
Object newOriginTimestamp = newDoc.getFieldValue(ORIGIN_TIMESTAMP);
  
Object oldOriginTimestamp = oldDoc.getFieldValue(ORIGIN_TIMESTAMP);
  
if (newOriginTimestamp != null && oldOriginTimestamp != null)
  
{
  
if (Long.valueOf(oldOriginTimestamp.toString()) < Long.valueOf(newOriginTimestamp.toString()))
  
{
  
newDoc.setField(ORIGIN_TIMESTAMP, oldOriginTimestamp);
  
}
  
}
  
// pass it up the chain
  
super.processAdd(cmd);
  
}
  

  
}
  

  1.将该类编译后生成jar包放到 /var/lib/solr/plugins目录下,或者你任意指定一个目录。
  2.配置solrconfig.xml加载该jar包。(注意修改jar包或者solrconfig.xml之后要reload collection)
  

<lib dir="/var/lib/solr/plugins" />  

  3.配置solrconfig.xml的默认update用哪个chain名字。
  

<requestHandler name="/update">  
<!-- See below for information on defining
  
updateRequestProcessorChains that can be used by name
  
on each Update Request
  
-->
  
<lst name="defaults">
  
<str name="update.chain">condition</str>
  
</lst>
  
</requestHandler>
  

  以及solrconfig.xml chain的流程。
  

<updateRequestProcessorChain name="condition">  
<processor />
  
<processor />
  
<processor />
  
<processor />
  
</updateRequestProcessorChain>
  

  *关于为什么放在DistibutedUpdateProcessFactory之后。
  https://wiki.apache.org/solr/Atomic_Updates
  2017.01.12优化:
  如下场景时,上面代码会出现问题:
  老的数据没有立即commit,还保存在TLog中,此时RealTimeGetComponet.getInputDocument方法获取不到老数据,导致处理逻辑不符合期望,来源时间不正确。
  代码优化如下:
  

SolrInputDocument oldDoc = RealTimeGetComponent.getInputDocumentFromTlog(core, indexedId);  

if (oldDoc == null)  
{
  
oldDoc
= RealTimeGetComponent.getInputDocument(core, indexedId);  
}
  

运维网声明 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-425678-1-1.html 上篇帖子: Solr-5.3.1 dataimport 导入mysql数据 下篇帖子: 【solr专题之中的一个】Solr高速入门
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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