更新API允许根据提供的脚本来更新文档。操作从索引获取文档(通过分片并发的),运行脚本(具有可选脚本语言和参数),并将结果建立索引(也允许删除或忽略该操作)。它使用版本控制来确保在“get”和“reindex”期间没有发生更新。
请注意,此操作仍然意味着文档的完整重新索引,它只是删除一些网络往返,并减少get和index之间版本冲突的机会。需要启用_source字段以使此功能正常工作。
为了演示,我们创建一个简单的文档:
PUT test/type1/1
{
"counter" : 1,
"tags" : ["red"]
}
现在,我们能执行以下脚本来递增计数器:
POST test/type1/1/_update
{
"script" : {
"inline": "ctx._source.counter += params.count",
"lang": "painless",
"params" : {
"count" : 4
}
}
}
我们可以在tags中添加一个tag(注意,如果tags存在,它将会添加它,由于它是一个列表):
除_source外,以下变量可通过ctx映射获得:_index、_type、_id、_version、_routing、_parent和_now(当前时间戳)。
我们还可以在文档中添加一个新的字段:
或者从文档中删除一个字段:
我们甚至可以改变所执行的操作。这个例子中删除文档如果标签字段包含green,否则什么也不做(noop):
更新API还支持传递一个部分文档,它将被合并到现有文档中(简单的递归合并,对象的内部合并,替换核心“键/值”和数组)。例如:
如果指定了doc和script,则忽略doc。最好是将部分文档的字段对放在脚本本身中。
如果指定了doc,它的值将与现有的_source合并。默认情况下,不更改任何内容的更新会探测到它们不会更改任何内容并返回“result”:“noop”,如下所示:
如果在发送请求之前name是new_name,则忽略整个更新请求。如果请求被忽略,则响应中的result元素返回noop。
您可以通过设置“detect_noop”为false来禁用此行为,如下所示:
如果文档不存在,则将upsert的内容作为新的文档插入。如果文档确实存在,那么script将被执行:
scripted_upsert
如果您希望无论文档是否存在都运行脚本——即脚本处理初始化文档替代upsert元素——则将scripted_upsert设置为true:
将doc_as_upsert设置为true而不是发送部分文档加上upsert文档,而将doc的内容用作upsert值:
更新操作支持如下查询字符串参数:
注意
更新API不支持外部版本控制(版本类型external&external_gte),因为它会导致Elasticsearch版本号与外部系统不同步。使用index API代替。