背景:基于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 class ConditionUpdateProcessFactory extends UpdateRequestProcessorFactory
{
@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" class="solr.UpdateRequestHandler">
<!-- 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 class="solr.LogUpdateProcessorFactory" />
<processor class="solr.DistributedUpdateProcessorFactory" />
<processor class="custom.solr.ConditionUpdateProcessFactory" />
<processor class="solr.RunUpdateProcessorFactory" />
</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);
}

Solr Update插件自定义Update Chain按条件更新索引的更多相关文章

  1. [jQuery]jQuery DataTables插件自定义Ajax分页实现

    前言 昨天在博客园的博问上帮一位园友解决了一个问题,我觉得有必要记录一下,万一有人也遇上了呢. 问题描述 园友是做前端的,产品经理要求他使用jQuery DataTables插件显示一个列表,要实现分 ...

  2. 【JAVA】FOR UPDATE 和 FOR UPDATE NOWAIT 区别 (转)

    1.for update 和 for update nowait 的区别:首先一点,如果只是select 的话,Oracle是不会加任何锁的,也就是Oracle对 select 读到的数据不会有任何限 ...

  3. [转]oracle for update和for update nowait的区别

    1概念小结:(针对以下引用区域内容) 1.1 普通select语句不加锁. 1.2 for update和for update nowait都试图将符合条件的数据加上行级锁.用于排斥其他针对这个表的写 ...

  4. Oracle 中 for update 和 for update nowait 的区别

    原文出处http://bijian1013.iteye.com/blog/1895412 一.for update 和 for update nowait 的区别 首先一点,如果只是select 的话 ...

  5. oracle for update和for update nowait

    原文地址:http://www.cnblogs.com/quanweiru/archive/2012/11/09/2762223.html 1.for update 和 for update nowa ...

  6. sql: oracle, for update和for update nowait的区别

    1. oracle for update和for update nowait的区别 http://www.cnblogs.com/quanweiru/archive/2012/11/09/276222 ...

  7. oracle for update和for update nowait(for update wait)的区别

    1.for update 和 for update nowait 的区别: 1.oracle 中执行select 操作读取数据不会有任何限制,当另外一个进程在修改表中的数据,但是并没有commit,所 ...

  8. oracle for update和for update nowait的区别 - 转

    1.for update 和 for update nowait 的区别: 首先一点,如果只是select 的话,Oracle是不会加任何锁的,也就是Oracle对 select 读到的数据不会有任何 ...

  9. oracle for update和for update nowait 的区别

    原文地址:http://www.cnblogs.com/quanweiru/archive/2012/11/09/2762223.html 1.for update 和 for update nowa ...

随机推荐

  1. java的征途

    前段时间应因缘梳理了下自己的 Java 知识体系, 成文一篇望能帮到即将走进或正在 Java 世界跋涉的程序员们. 第一张,基础图 大 约在 2003 年我开始知道 Java 的(当时还在用 Delp ...

  2. 查看服务器wwn是否在交换机侧

    判断port_state是否为Online状态,是的话,读取出port_name,即为wwn. #!/usr/bin/env python3 # -*- coding: UTF-8 -*- impor ...

  3. rpmbuild

    rpm2cpio xxx.rpm | cpio -div

  4. [Apple开发者帐户帮助]三、创建证书(8)撤销证书

    您可以根据证书类型和角色撤消证书.有关详细信息,请转到撤消权限. 要了解撤销证书时会发生什么,请转到Apple Developer支持中的证书. 所需角色:帐户持有人或管理员. 在“ 证书”,“标识符 ...

  5. Azure Command Line(Azure CLI)指南

    1.安装. MSI安装程序:https://aka.ms/installazurecliwindows https://docs.microsoft.com/zh-cn/cli/azure/insta ...

  6. 在redhat6上装1.8以下的docker

    因为目前1.8以上的docker最低要求是3.10的Linux内核,而我的内核版本远低于此. [root@localhost home]# uname -r -.el6.x86_64 鉴于我的vm上有 ...

  7. 【POJ2248、LOJ#10021】 Addition Chains

    事先预警:由于我太蒻了,本做法只能在POJ.LOJ等小数据(N<=100)平台上通过,在UVa(洛谷)上大数据并不能通过 戳我获得更好的观看效果 本题不用看,爆搜就是了,但是纯爆搜显然会爆时间, ...

  8. 网络流模板(模板题:POJ1273)

    模板题:POJ1273 EK: #include <queue> #include <cstdio> #include <cstring> #include < ...

  9. 6.10---mybatis的实体---接口---接口映射---主配置文件

  10. (转载)实例详解Android快速开发工具类总结

    实例详解Android快速开发工具类总结 作者:LiJinlun 字体:[增加 减小] 类型:转载 时间:2016-01-24我要评论 这篇文章主要介绍了实例详解Android快速开发工具类总结的相关 ...