1 需求分析

(1) 需求:

向Solr中的文档添加新的字段并赋值, 或者修改已有的字段, 对不修改的要保持原值, 也就是不能进行完全覆盖操作.

(2) 前提:

添加的字段(field)要提前在schema.xml文件中定义, 否则Solr无法处理这些字段, 肯定会导致添加失败.

关于schema.xml文件的配置, 可参考: Solr的schema.xml模式文件解读 (Solr的模式设计与优化)

(3) 分析: 我们可以使用Solr提供的原子更新, 来实现相关需求:

Solr支持的原子更新:

set: 修改指定文档中该field的值, 如果这个field已经存在, 则更新, 如果不存在, 则追加到这个文档中 —— 可以是单值, 也可以是multi-valued;

add: 向指定文档中的field字段添加值, 这个field必须是multi-valued类型的, 否则将出错 —— 只能是multi-valued;

inc: 对指定文档中数值类型的值进行自增操作 —— 只能是数值类型, 包括int、long、float、double.

2 需求实现

2.1 pom.xml依赖

<!-- 项目较早, 使用的是4.10.4版本的Solr -->
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>4.10.4</version>
</dependency>

2.2 Java代码示例

(1) 先获取Solr连接:

String zkHost= "ip:port,ip:port,ip:port";
// 扩大并发连接数
ModifiableSolrParams params = new ModifiableSolrParams();
params.set(HttpClientUtil.PROP_MAX_CONNECTIONS, 1000);
params.set(HttpClientUtil.PROP_MAX_CONNECTIONS_PER_HOST, 100);
HttpClient client = HttpClientUtil.createClient(params);
LBHttpSolrServer lbServer = new LBHttpSolrServer(client); CloudSolrServer solrServer = new CloudSolrServer(zkHost, lbServer);
// 为 Solr 连接设置默认的 Collection
solrServer.setDefaultCollection("C_Book"); // 设置ZooKeeper连接超时时间
solrServer.setZkClientTimeout(18000);
solrServer.setZkConnectTimeout(36000);

(2) 准备需要处理的Solr文档, 相关注意事项已经在代码注释中作了详细说明:

// 为了提高效率, 可以使用批量操作
Collection<SolrInputDocument> updateDocList = new ArrayList<>(); for (int i = 0; i < 5; ++i) {
SolrInputDocument doc = new SolrInputDocument();
// 局部更新需要指定文档的id(在schema.xml中配置的主键),
// 主键不需要添加set、add等信息, 其他需要原子更新的field需要构造为Map
doc.addField("id", i); // 局部更新需要借助Map, 这个Map的Key必须是“set”
Map<String, String> publisherMap = new HashMap<>();
publisherMap.put("set", "人民邮电出版社");
// 修改图书的出版社, key是field, value是上述的Map
doc.addField("publisher", publisherMap); // 在已有仓库的基础上, 再添加多个仓库, 注意: 此field必须是multi-valued类型
Map<String, List<String>> stockCityMap = new HashMap<>();
List<String> list = new ArrayList();
list.add("广州");
list.add("深圳");
// 局部添加需要借助Map, 这个Map的Key必须是“add”
stockCityMap.put("add", list);
// 修改图书的仓库城市, key是field, value是上述的Map
doc.addField("stockCity", stockCityMap); // 在已有图书价格的基础上: 每本增加9.50元, 注意: 此field必须是数值类型
Map<String, Long> priceMap = new HashMap<>();
// 局部自增需要借助Map, 这个Map的Key必须是“inc”
priceMap.put("inc", 9.50L);
// 修改图书的价格, key是field, value是上述的Map
doc.addField("price", priceMap); // _version_值为0: 如果待修改的文档存在, 则修改; 如果不存在, 则添加
doc.addField("_version_", 0); updateDocList.add(doc);
}

(3) 向SolrCloud中提交批量添加请求:

// 连接SolrCloud
solrServer.connect();
// 添加提交文档List
UpdateResponse rsp = solrServer.add(updateDocList); System.out.println("操作状态: " + rsp.getStatus() + ", 操作时间:" + rsp.getQTime()); // 提交策略: 不用手动提交, 交由Solr服务根据配置自动进行软提交;
// 如果要手动提交, 不要使用无参方法, 推荐指定提交策略: 是否等待刷新(建议不等待: 会阻塞)、等待可搜索(建议不等待: 会阻塞)、软提交
UpdateResponse rspCommit = solrServer.commit(false, false, true);
System.out.println("提交状态: " + " result:" + rspCommit.getStatus() + ", 操作时间: " + rspCommit.getQTime());

3 补充说明

3.1 关于文档中_version_的取值说明

(1) version < 0: 如果待修改的文档存在, Solr会拒绝修改; 如果不存在, 就添加这个文档.

(2) version = 0: 如果待修改的文档存在, 就更新这个文档; 如果不存在, 就添加这个文档.

(3) version = 1: 如果待修改待文档存在, 就更新这个文档; 如果不存在, Solr会拒绝修改它, 并抛出类似的错误信息:

version conflict for 1 expected=1 actual=-1

(4) version > 1: 如果文档的_version_值和传入的_version_值不同, Solr就会拒绝修改; 值相同时才执行修改.

3.2 store=true/false的区别

(1) 如果某个字段在schema.xml中指定了store=false, 那么即使这个字段有值, 在更新的时候也会被Solr丢弃, 而指定为store=true的字段则不会;

(2) 对于multi-field(多值)字段, 如果指定其store=false, 则在原子更新使用add的时候会级联清除该字段之前的数据.

参考资料

solr的原子更新/局部更新

版权声明

作者: 马瘦风(https://healchow.com)

出处: 博客园 马瘦风的博客(https://www.cnblogs.com/shoufeng)

感谢阅读, 如果文章有帮助或启发到你, 点个[好文要顶

Solr 18 - 通过SolrJ局部更新Solr中的文档 (原子操作、非覆盖操作)的更多相关文章

  1. MongoDB学习(操作集合中的文档)

    文档概念 文档的数据结构和JSON基本一样. 所有存储在集合中的数据都是BSON格式. BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON. 插入文档 insert()方法 ...

  2. 从单一图像中提取文档图像:ICCV2019论文解读

    从单一图像中提取文档图像:ICCV2019论文解读 DewarpNet: Single-Image Document Unwarping With Stacked 3D and 2D Regressi ...

  3. JavaScript中的文档模式和严格模式

    JavaScript中的文档模式和严格模式 语法模式有普通模式和严格模式两种 普通模式:正常的JavaScript语法拼写以及代码编写(相对于严格模式存在着语法上的不严谨),尽可能的识别错误以及不规范 ...

  4. 孤荷凌寒自学python第五十四天使用python来删除Firebase数据库中的文档

    孤荷凌寒自学python第五十四天使用python来删除Firebase数据库中的文档 (完整学习过程屏幕记录视频地址在文末) 今天继续研究Firebase数据库,利用google免费提供的这个数据库 ...

  5. C# 中使用Word文档对图像进行操作

    C# 中使用Word文档对图像进行操作 Download Files: ImageOperationsInWord.zip 简介 在这篇文章中我们可以学到在C#程序中使用一个Word文档对图像的各种操 ...

  6. Mongoose在向集合中插入文档时的集合命名问题

    Mongoose使用结构化的模式应用到MongoDB集合,为MongoDB Node.js原生驱动程序提供了更多的功能和简化了数据库操作. 从创建连接到向数据库中写入一个条数据经历了以下步骤: 1.连 ...

  7. 在SharePoint 2013 中使用文档库Scheduling (计划公布功能)

    本文讲述在SharePoint2013 中使用文档库Scheduling (计划公布功能)的步骤和注意的事项. 文档库Scheduling (计划公布功能) 用于设定当文档通过审批后特定的时间区间内才 ...

  8. hibernate中出现 文档根元素 "hibernate-mapping" 必须匹配 DOCTYPE 根 "hibernate-configuration"

    hibernate中出现 文档根元素 "hibernate-mapping" 必须匹配 DOCTYPE 根 "hibernate-configuration"  ...

  9. jquery-7 jquery中的文档处理方法有哪些(方法的参数表示功能增强)

    jquery-7 jquery中的文档处理方法有哪些(方法的参数表示功能增强) 一.总结 一句话总结:多看参考文档,多看主干目录.一般的功能分两个方法来实现,一个对应标签,一个对应标签和事情,比如克隆 ...

随机推荐

  1. 使用Adorner显示WPF控件的边界点

    原文:使用Adorner显示WPF控件的边界点 当我们拖动WPF控件时,我们为了更清楚地需要显示控件,一般我们会在WPF控件所围成的矩形区域的四个边界点上作一个特殊的记号(比如圆点).如下图: 在Wi ...

  2. 国家模式c++

    状态模式(State Pattern)是设计模式的一种,属于行为模式. 定义(源于Design Pattern):当一个对象的内在状态改变时同意改变其行为,这个对象看起来像是改变了其类. 状态模式主要 ...

  3. Leetcode 268 Missing Number 位运算

    题意:先将0, 1, 2, ..., n放入数组,然后去掉其中一个值,找到那个值. 这题与singe number 是一个类型,变形的地方就是首先需要将0, 1, 2, ..., n再次放入这个数组, ...

  4. Linux性能测试 /proc目录

    /proc文件系统 - 各种内核信息/proc目录下文件提供了很多不同硬件设备和内核的详细信息.更多详情参见Linux kernel /proc.一般/proc例如: [root@SM155 proc ...

  5. Android - 小的特点 - 使用最新版本ShareSDK手册分享(分享自己定义的接口)

    前太实用Share SDK很快分享,但官员demo快捷共享接口已被设置死,该公司的产品还设计了自己的份额接口,这需要我手动共享. 读了一堆公文,最终写出来,行,废话,进入主题. 之前没实用过Share ...

  6. mysql常见操作汇总 专题

    mysql中in多个字段 1. 基本用法 SELECT * FROM USER WHERE , , ); 2. 多个字段同时使用 SELECT * FROM USER WHERE (, ),(, ), ...

  7. WPF 使用字体引发的 CLR20r3 问题排查

    开发机器上运行完好,拷贝置目标机器上出现此问题 问题排查: 计算机-->管理-->事件查看器--->windows日志-->应用程序 Application Error  看不 ...

  8. php 将一个二维数组中两个相同的value 相同 指定值相加

    array(3) { [0]=> array(7) { ["mlid"]=> int(1) ["num"]=> int(1) ["c ...

  9. SQLServer2008-2012开启远程连接的配置方法

    一.远程连接端口设置(很关键的一步)1.在服务器上打开SQL Server Configuration Manager.选择SQL Server配置管理器->SQL Server 网络配置-&g ...

  10. tensorflow 1.0 学习:模型的保存与恢复

    将训练好的模型参数保存起来,以便以后进行验证或测试,这是我们经常要做的事情.tf里面提供模型保存的是tf.train.Saver()模块. 模型保存,先要创建一个Saver对象:如 saver=tf. ...