Update API
Update API可以根据提供的脚本更新文档。 该操作从索引获取文档,运行脚本(脚本语言和参数是可选的),并返回操作的结果(也允许删除或忽略该操作)。 使用版本控制来确保在“get”(查询文档)和“reindex”(重新索引文档)期间没有发生更新。
值得注意的是,该操作会重新索引文档(也就是说更新操作会先查文档,对文档合并,删除之前的文档,重新添加合并的文档。),它只是减少了网络往返以及减少了get(获取文档)和index(索引文档)之间版本冲突的可能性。 需要启用_source字段才能使此特性生效。
比如,索引一个简单的文档:
PUT test/_doc/1
{
"counter" : 1,
"tags" : ["red"]
}
Scripted updates
以下示例演示了如何执行一个增加counter的脚本:
POST test/_doc/1/_update
{
"script" : {
"source": "ctx._source.counter += params.count",
"lang": "painless",
"params" : {
"count" : 4
}
}
}
现在我们就可以往tags列表里添加一个tag(注意,如果tag存在,仍会添加,因为它是一个list)
POST test/_doc/1/_update
{
"script" : {
"source": "ctx._source.tags.add(params.tag)",
"lang": "painless",
"params" : {
"tag" : "blue"
}
}
}
不止_source,以下变量也可以通过ctx来取得: _index, _type, _id, _version, _routing and _now(当前的时间戳)
以下示例演示了如何获取_id,比如:
POST test/_doc/1/_update
{
"script" : "ctx._source.tags.add(ctx._id)"
}
也可以向文档添加新字段:
POST test/_doc/1/_update
{
"script" : "ctx._source.new_field = 'value_of_new_field'"
}
从文档移除某个字段:
POST test/_doc/1/_update
{
"script" : "ctx._source.remove('new_field')"
}
甚至可以改变已执行的操作。 以下示例:如果标签字段包含green,将删除doc,否则它不执行任何操作(即该操作会被忽略,返回noop):
POST test/_doc/1/_update
{
"script" : {
"source": "if (ctx._source.tags.contains(params.tag)) { ctx.op = 'delete' } else { ctx.op = 'none' }",
"lang": "painless",
"params" : {
"tag" : "green"
}
}
}
更新部分文档
update API还支持传递部分文档,该部分文档将合并到现有文档中(简单的递归合并,对象的内部合并,替换核心"keys/values"和数组)。 要完全替换现有文档,应使用index API。 以下示例演示了如何使用部分更新向现有文档添加新字段:
POST test/_doc/1/_update
{
"doc" : {
"name" : "new_name"
}
}
如果同时指定了doc和script,会报错。 最好是将部分文档的字段对放在脚本本身中(目前我还不知道该怎么操作)。
POST test/_doc/1/_update
{
"doc" : {
"age" : "18"
},
"script" : {
"source": "ctx._source.counter += params.count",
"lang": "painless",
"params" : {
"count" : 4
}
}
}
返回结果如下:
{
"error": {
"root_cause": [
{
"type": "action_request_validation_exception",
"reason": "Validation Failed: 1: can't provide both script and doc;"
}
],
"type": "action_request_validation_exception",
"reason": "Validation Failed: 1: can't provide both script and doc;"
},
"status": 400
}
检测noop更新
如果指定了doc,则其值将与现有_source合并。 默认情况下,不更改任何内容的更新,会检测到并会返回“result”:“noop”,如下所示:
POST test/_doc/1/_update
{
"doc" : {
"name" : "new_name"
}
}
如果在发送请求之前name是new_name,则忽略整个更新请求。 如果请求被忽略,响应中的result元素将返回noop。
{
"_index": "test",
"_type": "_doc",
"_id": "1",
"_version": 2,
"result": "noop",
"_shards": {
"total": 0,
"successful": 0,
"failed": 0
}
}
设置"detect_noop": false可以禁用这种默认行为:
POST test/_doc/1/_update
{
"doc" : {
"name" : "new_name"
},
"detect_noop": false
}
Upserts
如果文档尚不存在,则upsert元素的内容将作为新文档插入。 如果文档确实存在,则执行脚本:
POST test/_doc/1/_update
{
"script" : {
"source": "ctx._source.counter += params.count",
"lang": "painless",
"params" : {
"count" : 4
}
},
"upsert" : {
"counter" : 1
}
}
当然,不一定非得脚本,下面这样也是可以的,文档不存在的时候执行upsert内容,文档存在的时候执行doc的内容:
POST test/_doc/1/_update
{
"doc" : {
"name" : "new_name"
},
"upsert" : {
"counter" : 10
}
}
scripted_upsert
如果希望无论文档是否存在,都运行脚本(即使用脚本处理初始化文档而不是upsert元素)可以将scripted_upsert设置为true:
POST sessions/session/dh3sgudg8gsrgl/_update
{
"scripted_upsert":true,
"script" : {
"id": "my_web_session_summariser",
"params" : {
"pageViewEvent" : {
"url":"foo.com/bar",
"response":404,
"time":"2014-01-01 12:32"
}
}
},
"upsert" : {}
}
下面来看看和直接写脚本不用upsert的区别,当文档不存在时,直接下面这样写会报错。
POST test/_doc/1/_update
{
"scripted_upsert":true,
"script" : {
"source": "ctx._source.counter += params.count",
"lang": "painless",
"params" : {
"count" : 4
}
}
}
返回错误消息如下:
{
"error": {
"root_cause": [
{
"type": "document_missing_exception",
"reason": "[_doc][1]: document missing",
"index_uuid": "YgmlkeEERGm20yUBDJHKtQ",
"shard": "3",
"index": "test"
}
],
"type": "document_missing_exception",
"reason": "[_doc][1]: document missing",
"index_uuid": "YgmlkeEERGm20yUBDJHKtQ",
"shard": "3",
"index": "test"
},
"status": 404
}
设置scripted_upsert:true,当文档不存在时,执行下面的代码:
POST test/_doc/1/_update
{
"scripted_upsert":true,
"script" : {
"source": "ctx._source.counter += params.count",
"lang": "painless",
"params" : {
"count" : 4
}
},
"upsert" : {
"counter" : 10
}
}
返回的结果如下:
{
"_index": "test",
"_type": "_doc",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 6,
"_primary_term": 1
}
可见,执行成功了,下面来看看文档:
{
"_index": "test",
"_type": "_doc",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"counter": 14
}
}
counter的值为14,可见是先执行了upsert的内容,然后执行了脚本。
doc_as_upsert
将doc_as_upsert设置为true将使用doc的内容作为upsert值,而不是发送部分doc加上upsert文档:
POST test/_doc/1/_update
{
"doc" : {
"name" : "new_name"
},
"doc_as_upsert" : true
}
下面来看看和直接写doc的区别:
POST test/_doc/1/_update
{
"doc" : {
"name" : "new_name"
}
}
当文档不存在时,设置doc_as_upsert为true,可以成功执行。而上面这种情况会报错,提示文档不存在。如果向下面这样写会出现什么情况呢?
POST test/_doc/1/_update
{
"doc" : {
"name" : "new_name"
},
"upsert" : {
"counter" : 10
},
"doc_as_upsert" : true
}
结果是upsert永远不会被执行,不管文档存在不存在,始终执行的是doc的内容。
Parameters
update操作支持以下query-string(跟在请求url后面)参数:
retry_on_conflict:在更新的get和indexing阶段之间,另一个进程可能已经更新了同一文档。 默认情况下,会更新失败,因为版本冲突异常。 retry_on_conflict参数控制在最终抛出异常之前重试更新的次数。
routing:路由用于将更新请求路由到正确的分片,以及在将要更新的文档不存在时为upsert请求设置路由。 不能用于更新现有文档的路由。
timeout:设置等待分片变为可用的时间。
wait_for_active_shards:在继续更新操作之前需要处于活动状态的分片副本数。 详情请见此处。
refresh:控制何时该请求所做的更改对搜索可见。 看refresh。
_source:允许控制是否返回以及如何在响应中返回更新的源。 默认情况下,不会返回更新的源。 请参阅源过滤了解详细信息
version:update API在内部使用Elasticsearch的versioning支持,以确保在更新期间文档不会更改。 可以使用version参数指定仅在文档版本与指定版本匹配时才更新文档。
update API不支持internal以外的版本,也就是说update API不支持外部(版本类型external&external_gte)或强制(版本类型force)版本,因为它会导致Elasticsearch版本号与外部系统不同步。 请改用index API。
官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html
Update API的更多相关文章
- elasticsearch6.7 05. Document APIs(6)UPDATE API
5. UPDATE API 更新操作可以使用脚本来更新.更新的时候会先从索引中获取文档数据(在每个分片中的集合),然后运行脚本(使用可选的脚本语言和参数),再果进行索引(还允许删除或忽略该操作).它使 ...
- elasticsearch 基础 —— Update API
Update API 更新API允许基于提供的脚本更新文档.该操作从索引获取文档(与分片并置),运行脚本(使用可选的脚本语言和参数),并对结果进行索引(也允许删除或忽略操作).它使用版本控制来确保在& ...
- elasticsearch6.7 05. Document APIs(7)Update By Query API
6.Update By Query API _update_by_query 接口可以在不改变 source 的情况下对 index 中的每个文档进行更新.这对于获取新属性或其他联机映射更改很有用.以 ...
- elasticsearch 基础 —— Update By Query API
Update By Query API 最简单的用法是_update_by_query在不更改源的情况下对索引中的每个文档执行更新.这对于获取新属性或其他一些在线映射更改很有用 .这是API: POS ...
- elasticsearch中常用的API
elasticsearch中常用的API分类如下: 文档API: 提供对文档的增删改查操作 搜索API: 提供对文档进行某个字段的查询 索引API: 提供对索引进行操作,查看索引信息等 查看API: ...
- elasticsearch中的API
elasticsearch中的API es中的API按照大类分为下面几种: 文档API: 提供对文档的增删改查操作 搜索API: 提供对文档进行某个字段的查询 索引API: 提供对索引进行操作 查看A ...
- postgresql9.4新特性jsonb学习-update更新操作
先科普下概念:PgSQL9.4 新增 JSONB 数据类型, JSONB 同时属于 JSON (JavaScript Object Notation) 数据类型,jsonb 和 json 的输入数据几 ...
- elasticsearch基本操作之--java基本操作 api
/** * 系统环境: vm12 下的centos 7.2 * 当前安装版本: elasticsearch-2.4.0.tar.gz */ 默认进行了elasticsearch安装和ik安装, 超时配 ...
- Bulk API
承接上文,使用Java High Level REST Client操作elasticsearch Bulk API 高级客户端提供了批量处理器以协助批量请求 Bulk Request BulkReq ...
随机推荐
- goroute应用-模拟远程调用RPC
go语言简单模拟RPC,详见个人新博客:blog.dlgde.cn 代码如下: package main import ( "errors" "fmt" &qu ...
- 从头开始学gradle【Gradle 构建基础】
构建基础 Project 和 task:projects 和 tasks是 Gradle 中最重要的两个概念. 任何一个 Gradle 构建都是由一个或多个 projects 组成.每个 projec ...
- C++入门篇十
静态成员变量:可以共享数据,类内声明,类外初始化(实现) // 静态成员变量.cpp : 此文件包含 "main" 函数.程序执行将在此处开始并结束. // #include &q ...
- Oracle建立全文索引详解
Oracle建立全文索引详解1.全文检索和普通检索的区别 不使用Oracle text功能,当然也有很多方法可以在Oracle数据库中搜索文本,比如INSTR函数和LIKE操作: SELECT *FR ...
- IE8引用jQuery报$或者jQuery未定义
最近公司做的项目要求兼容到IE8,结果在页面调试的时候出了个bug,在IE8上面一直报错$未定义,或者jQuery未定义,导致页面上面写的jQuery全部失效,在Chrome浏览器没有任何问题.很是头 ...
- ajax导致Echarts不显示饼图数据、柱状图数据只显示气泡的问题。
1.ajax导致Echarts不显示饼图数据.柱状图数据只显示气泡的问题. ajax的同步.这个同步的意思是当JS代码加载到当前ajax的时候会把页面里所有的代码停止加载,页面出去假死状态,当这个aj ...
- jackson json转bean忽略没有的字段 not marked as ignorable
@JsonIgnore注解用来忽略某些字段,可以用在Field或者Getter方法上,用在Setter方法时,和Filed效果一样.这个注解只能用在POJO存在的字段要忽略的情况,不能满足现在需要的情 ...
- 简易promise的实现(一)
code 最近在思考promise的实现原理 于是准备自己写一个简单的demo 一开始想到的问题有两个 1.链式调用 2.异步顺序执行 -------------------------------- ...
- MockPlus原型设计介绍
MockPlus原型设计介绍 在第八周的课堂上,王文娟老师在校园系统上发布了对于自行选择的原型设计软件进行资料查找以及自学的任务.因为之前的课程学习需要,我们已经大概掌握了原型设计软件Axure的使用 ...
- 使用python将数据写入excel
先来个简单的例子: #!/usr/bin/python #coding=utf-8 # ======================================================== ...