ES-更新现有文档

ES的更新API允许发送文档所需要做的修改,而且API会返回一个答复,告知操作是否成功。
更新流程如下

1. 检索现有的文档。为了使这步奏效,必须打开_source字段,否则ES并不知道原有文档的内容。
2. 进行制定的修改。例如,如果文档是
{"name":"Elasticsearch Denver","organizer":"Lee"}
修改组织者,修改后的文档是
{"name":"Elasticsearch Denver","organizer":"Roy"}
3. 删除旧的文档,在其原有位置索引新的文档(包含修改的内容)。

使用更新API

(1).通过发送部分文档,增加或替换现有文档的一部分。
(2).如果文档不存在,当发送部分文档或者脚本时,请确认文档是否被创建。如果文档之前不存在,可以指定被索引的文档原始内容
(3).发送脚本来更新文档。

1. 发送部分文档

发送部分的文档内容,包含所需要设置的字段值,是更新一个或多个字段最容易的方法。为了实现这个操作,需要将这些信息通过HTTP POST请求发送到该文档URL的_update端点。
先插入一条新文档

curl -XPUT 'localhost:9200/get-together/group/1?pretty' -d '{
"name":"Elasticsearch Denver",
"organizer":"Lee"
}'

更新

curl -XPOST 'localhost:9200/get-together/group/1/_update?pretty' -d '{
"doc":{
"organizer":"Roy"
}
}'

这条命令设置了在doc下指定的字段,将其值设置为所提供的值。它并不考虑这些字段之前的值,也不考虑这些字段之前是否存在。如果之前整个文档是不存在的,那么更新操作会失败,并提示文档缺失。
验证

FengZhendeMacBook-Pro:cv FengZhen$ curl 'localhost:9200/get-together/group/1?pretty'
{
"_index" : "get-together",
"_type" : "group",
"_id" : "",
"_version" : ,
"found" : true,
"_source" : {
"name" : "Elasticsearch Denver",
"organizer" : "Roy"
}
}

注意:在更新的时候,要牢记可能存在冲突。例如,如果将分组的组织者修改为”Roy”,还有人将其修改为”Feng”,那么其中一次更新会被另一次覆盖。为了控制这种局面,可以使用版本功能。

2. 使用upsert来创建尚不存在的文档

为了处理更新时文档不存在的情况,可以使用upsert.(update和insert的混成词)
如果被更新的文档不存在,可以在JSON的upsert部分中添加一个初始文档用于索引。

curl -XPOST 'localhost:9200/get-together/group/1/_update?pretty' -d '{
"doc":{
"organizer":"Roy"
},
"upsert":{
"name":"Elasticsearch Denver",
"organizer":"Roy"
}
}'

3. 通过脚本来更新文档

(1).默认的脚本语言是Groovy。它的语法和Java相似,但是作为脚本,使用更加简单。
(2).由于更新要获得现有文档的_source内容,修改并重新索引新的文档,因此脚本会修改_source中的字段。使用ctx._source来使用_source,使用ctx._source[字段名]来引用某个指定的字段。
(3).如果需要变量,推荐在params下作为参数单独定义,和脚本本身区分开来。这是因为脚本需要编译,一旦编译完成,就会被缓存。如果使用不同参数,多次运行同样的脚本,脚本只需要编译一次。之后的运行都会从缓存中获取现有脚本。相比每次不同的脚本,这样运行会更快,因为不同的脚本每次都需要编译。

注意:由于安全因素,通过API运行以下脚本可能默认的被禁止,这取决于所运行的ES版本。这成为动态脚本,在elasticsearch.yml中将script.disable_dynamic设置为false,就可以打开这个功能。

curl -XPUT 'localhost:9200/online-shop/shirts/1?pretty' -d '{
"caption":"Learning Elasticsearch",
"price":
}' curl -XPOST 'localhost:9200/online-shop/shirts/1/_update?pretty' -d '{
"script":"ctx._source.price += price_diff",
"params":{
"price_diff":
}
}' FengZhendeMacBook-Pro:cv FengZhen$ curl 'localhost:9200/online-shop/_search?pretty'
{
"took" : ,
"timed_out" : false,
"_shards" : {
"total" : ,
"successful" : ,
"failed" :
},
"hits" : {
"total" : ,
"max_score" : 1.0,
"hits" : [ {
"_index" : "online-shop",
"_type" : "shirts",
"_id" : "",
"_score" : 1.0,
"_source" : {
"caption" : "Learning Elasticsearch",
"price" :
}
} ]
}
}

可以看到,这里使用的是ctx._source.price而不是ctx._source[‘price’].这是指向price字段的另一个方法。

通过版本来实现并发控制

如果同一时刻多次更新都在执行,将面临并发的问题。ES支持并发控制,为每篇文档设置了一个版本号。最初被索引的文档版本是1。当更新操作重新索引它的时候,版本号就设置为2了。如果与此同时另一个更新将版本设置为2,那么就会产生冲突,目前的更新也会失败。可以重试这个更新操作,如果不再有冲突,那么版本就会设置为3.
并发控制流程如下

curl -XPOST 'localhost:9200/online-shop/shirts/1/_update?pretty' -d '{
"script":"Thread.sleep(10000);ctx._source.price = 2"
}' curl -XPOST 'localhost:9200/online-shop/shirts/1/_update?pretty' -d '{
"script":"ctx._source.caption = \"Knowing Elasticsearch\""
}'

(1).索引文档然后更新它
(2).更新1在后台启动,有一定时间的等待(睡眠)
(3).在睡眠期间,发出另一个update的指令来修改文档。变化发送在更新1获取原有文档之后、重新索引回去之前。
(4).由于文档的版本已经变为2,更新1就会失败,而不会取消更新2所做的修改。这个时候有就机会重试更新1,然后进行版本为3的修改。
这种并发控制称为乐观锁,因为它允许并行的操作并假设冲突时很少出现的,真的出现时就抛出错误。它和悲观锁是相对的,悲观锁通过锁住可能引起冲突的操作,第一时间预防冲突。

1. 冲突发生时自动重试更新操作

当版本冲突出现的时候,可以再应用程序中处理。如果是更新操作,可以再次尝试,但是也可以通过设置retry_on_conflict参数,让ES自动重试

curl -XPOST 'localhost:9200/online-shop/shirts/1/_update?retry_on_conflict=3' -d '{
"script":"ctx._source.price = 2"
}'

2.索引文档的时候使用版本号

更新文档的另一个方法是不使用更新API,而是在同一个索引、类型和ID之处索引一个新的文档。这样的操作会覆盖现有的文档,这种情况下仍然可以使用版本字段来进行并发控制。为了实现这一点,要设置HTTP请求中的version参数。其值应该是期望该文档要拥有的版本号(当前的版本号)。如:如果认为现有的版本已经是3,一个重新索引的请求如下

curl -XPUT 'localhost:9200/online-shop/shirts/1?version=3' -d '{
"caption":"i konw about es versioning",
"price":""
}'

如果现有的版本实际上不是3,name这个操作就会抛出版本冲突异常并失败。
有了版本号就可以安全的索引和更新文档了。

使用外部版本

目前为止都是使用ES的内部版本,每次操作,无论是索引还是更新,ES都会自动的增加版本号。如果数据源是另一个数据存储,也许在那里有版本控制系统。例如,一种基于时间戳的系统。
为了使用外部版本,需要为每次请求添加version_type=external,以及版本号

curl -XPUT 'localhost:9200/online-shop/shirts/1?version=4&version_type=external' -d '{
"caption":"i konw about es versioning",
"price":""
}'

这将使ES接受任何版本号,只要比现有版本高,而且ES也不会自己增加版本号。

Elasticsearch-更新现有文档的更多相关文章

  1. elasticsearch更新doc文档

    在elasticsearch-head中: http://localhost:9200/my_index/products/2/ _update { "script" : { &q ...

  2. Elasticsearch 7.x文档基本操作(CRUD)

    官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/docs.html 1.添加文档 1.1.指定文档ID PUT ...

  3. elasticsearch 基础 —— 分布式文档存储原理

    路由一个文档到一个分片中 当索引一个文档的时候,文档会被存储到一个主分片中. Elasticsearch 如何知道一个文档应该存放到哪个分片中呢?当我们创建文档时,它如何决定这个文档应当被存储在分片  ...

  4. MongoDB(二)创建更新删除文档

    插入并保存文档操作 用insert向目标集合插入文档,如果没有_id键则会自动添加.最后自动保存. >db.foo.insert({"bar":"baz" ...

  5. 实时更新Excel文档外部数据源的数据

    实时更新Excel文档外部数据源的数据 单元格区域.Excel 表.数据透视表或数据透视图均可以连接到外部数据源(数据源:用于连接数据库的一组存储的"源"信息.数据源包含数据库服务 ...

  6. 利用 Github Actions 自动更新 docfx 文档

    利用 Github Actions 自动更新 docfx 文档 Intro docfx 是微软出品一个 .NET API 文档框架,有一个理念是代码即文档,会根据项目代码自动生成 API 文档,即使没 ...

  7. mongodb批量更新操作文档的数组键

    persons文档的数据如下: > db.persons.find(){ "_id" : 2, "name" : 2 }{ "_id" ...

  8. elasticsearch 官方监控文档 老版但很有用

    https://zhaoyanblog.com/page/1?s=elasticsearch 监控每个节点(jvm部分) 操作系统和进程部分 操作系统和进程部分的含义是很清楚的,这里不会描述的很详细. ...

  9. 5.ElasticSearch系列之文档的基本操作

    1. 文档写入 # create document. 自动生成 _id POST users/_doc { "user" : "shenjian", " ...

随机推荐

  1. AOP初步

    一刀切的AOP基础 软件开发的目的,最终是为了解决各种需求,包括业务和系统的,使用OOP可以对业务需求等普通关注点进行很好的抽象和封装,并且使之模块化. 但OOP却无法解决类似于日志.安全.事务等系统 ...

  2. vps能ping通但是ssh无法连接

    一.全国ping测试网页https://tools.ipip.net/ping.php 如果100%丢包率,那么肯定被q了,如果没有,也不一定没被q,进入下一步 二.国内外端口扫描测试http://t ...

  3. 【知识库】-数据库_MySQL之高级数据查询:去重复、组合查询、连接查询、虚拟表

    简书作者:seay 文章出处: 关系数据库SQL之高级数据查询:去重复.组合查询.连接查询.虚拟表 回顾:[知识库]-数据库_MySQL之基本数据查询:子查询.分组查询.模糊查询 Learn [已经过 ...

  4. [CSP-S模拟测试]:答题(meet in the middle)

    题目传送门(内部题142) 输入格式 输入文件的第一行为两个数$n,P$. 接下来一行$n$为个正整数,表示每道题的分数. 输出格式 输出一行一个正整数,为至少需要获得的分数. 样例 样例输入: 2 ...

  5. Word文档怎么从第二页加页码

    1.首先将光标放到首页的最后位置 2.“页面布局”—“分隔符”—“下一页” 3.“插入”—“页码”—选一种样式的页码 4.将光标定位到第二页的页脚处,“设计”—取消“链接到前一条页眉” 5.将第二页的 ...

  6. storm备忘

    [命令]storm rebalance topology-name [-w wait-time-secs] [-n new-num-workers] [-e component=parallelism ...

  7. C++面试出现频率最高的30道题目

    http://blog.csdn.net/wangshihui512/article/details/9092439 1.new.delete.malloc.free关系 delete会调用对象的析构 ...

  8. LC 163. Missing Ranges 【lock, hard】

    Given a sorted integer array nums, where the range of elements are in the inclusive range [lower, up ...

  9. ASP.Net Core承载外部程序集

    故事背景   一般情况下ASP.Net Core项目配置可以直接在appsetting.json中添加,也可以在项目中添加新的配置文件.但如果想和其他项目一起实现配置文件通用呢?我们可以用绝对定位去访 ...

  10. MySQL如何查询某个字段长度最大的记录

    转: MySQL如何查询某个字段长度最大的记录 2017年06月24日 13:12:15 翔云123456 阅读数 18348   版权声明:本文为翔云原创文章,未经博主允许不得转载. https:/ ...