[toc]
1. 单文档 Update API
update API 依据提供的script更新文档; 从索引中获取document, 执行脚本, 并对新的后果进行索引.
如何确保 get 和 reindex 期间没有产生更新? --> 应用版本控制
;
这种操作依然意味着对文档进行残缺的从新索引, 它只是移除了一些网络往返损耗,并缩小了get和索引之间版本抵触的机会.
1. script更新: 数值计算
示例: 新建一个document到 test 索引, 而后批改 counter=counter+4; 而后为tags新增一个 blue的色彩:
#1. 新建一个document到 test 索引PUT test/_doc/1{ "counter" : 1, "tags" : ["red"]}
将 "counter"的值加上给定的参数:
POST test/_update/1{ "script" : { "source": "ctx._source.counter += params.count", "lang": "painless", "params" : { "count" : 4 } }}
查看以后: GET test/_source/1
{ "counter" : 5, "tags" : [ "red" ]}
同理: counter=counter*2:
POST test/_update/1{ "script": { "source": "ctx._source.counter *= params.val", "params": { "val": 2 } }}
2. script更新: 数组(汇合)减少/删除
2.1 减少一个 yellow:
POST test/_update/1{ "script": { "source": "ctx._source.tags.add(params.clr)", "params": {"clr": "yellow"} }}
output:
{ "counter" : 10, "tags" : [ "red", "yellow" ]}
2.2 删除(留神是索引)
理论是ArrayList
的办法!
POST test/_update/1{ "script": { "source": "ctx._source.tags.remove(params.val)", "params": { "val": 0 } }}
{ "counter" : 10, "tags" : [ "yellow" ]}
2.3 clear()清空
同理, 能够调用 ArrayList
的其余办法: 比方 :
POST test/_update/1{ "script": { "source": "ctx._source.tags.clear()" }}
2.4 如何删除匹配的内容
如果当初 tags = ["yello", "red", "blue"], 要删除 "red", 依据内容而非索引:
POST test/_update/1{ "script": { "source": "if (ctx._source.tags.contains(params.val)) {ctx._source.tags.remove(ctx._source.tags.indexOf(params.val));}", "params": { "val": "red" } }}
GET test/_source/1
output:
{ "counter" : 10, "tags" : [ "yellow", "blue" ]}
留神: script.source 里的";"能够不要的;
2.5 script更新: ctx的其余内置变量
除了 _source
之外,ctx映射还提供了以下变量: _index
、_type
、_id
、_version
、_routing
和 _now
(以后工夫戳)。
2.6 script更新: 减少/删除字段entry
咱们给 test 索引中的 文档 1 新增一个字段: "addr": "beijing":
# update 减少字段entryPOST test/_update/1{ "script": { "source": "ctx._source.addr='beijing'" }}# 再减少一条POST test/_update/1{ "script": { "source": "ctx._source.location='yizhuang'" }}
GET test/_source/1
{ "counter" : 10, "tags" : [ "yellow" ], "addr" : "beijing", "location" : "yizhuang"}
删除:
# update 删除字段POST test/_update/1{ "script": { "source": "ctx._source.remove('location')" }}
GET test/_source/1
:
{ "counter" : 10, "tags" : [ "yellow" ], "addr" : "beijing"}
3. doc新增字段:
除了应用 script 外, 也能够应用 doc 来新增字段; 如果二者皆有, 会报错!
POST test/_update/1{ "doc" : { "loc" : "yz" }}
{ "counter" : 10, "tags" : [ "yellow" ], "addr" : "beijing", "loc" : "yz"}
如果指定了doc,那么它的值将与现有的_source合并; 如果 doc执行了屡次, 数据并没有变动, \_version和 \_seq\_no都不会更新! "result" : "noop"
4. upsert 更新+插入
4.1 script+upsert形式
如果文档还不存在,那么upsert元素的内容将作为新文档插入。如果该文档存在,则执行脚本:
DELETE test/_doc/2
咱们先执行此操作删除id=2的document; 而后执行上面 upsert 操作:
POST test/_update/2{ "script" : { "source": "ctx._source.counter += params.count", "lang": "painless", "params" : { "count" : 4 } }, "upsert" : { "counter" : 2, "name": "ifnotexists" }}
因为此刻没有 id=2的文档, 所以默认+=操作时是不会有的; 这样的话, upsert中的内容就会作为文档的内容保留;
这是 反复下面的 upsert 操作一次!! 再查后果: GET test/_source/2
{ "counter" : 6, "name" : "ifnotexists"}
能够看到, counter就是 2+4了;
4.2 doc形式的upsert
doc形式也能够实现upsert: 如下: 如果单纯是在下面有id=2的document的根底上执行上面:
POST test/_update/2{ "doc": { "gender": "male" }, "doc_as_upsert": true}
只是减少了一个 gender的字段!
{ "counter" : 6, "name" : "ifnotexists", "gender" : "male"}
当初删掉document: DELETE test/_doc/2
, 就会体现为 upsert的性能了, 此时 GET test/_source/2
:
{"gender" : "male"}
5. update的其余参数
timeout/wait_for_active_shards/version, 以及 if_seq_no + if_primary_term
5.1 if_seq_no+if_primary_term
POST test/_update/2?if_seq_no=31&if_primary_term=1{ "script": { "source": "ctx._source.counter=params.val", "params": { "val": 3 } }}
如果 _seq_no
和 _primary_term
匹配, 才执行更新, 否则报错!