前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >elasticsearch文档Update API

elasticsearch文档Update API

作者头像
江南一点雨
发布2019-03-07 10:51:07
1.7K0
发布2019-03-07 10:51:07
举报
文章被收录于专栏:玩转JavaEE玩转JavaEE

通过前面两篇文章的阅读,相信读者已经熟练掌握 DeleteByQuery的用法了,本文则来继续看文档的Update API。

本文是Elasticsearch系列的第十四篇,阅读前面的文章,有助于更好的理解本文:


1.elasticsearch安装与配置 2.初识elasticsearch中的REST接口 3.elasticsearch修改数据 4.elasticsearch文档操作 5.elasticsearch API约定(一) 6.elasticsearch API约定(二) 7.elasticsearch文档读写模型 8.elasticsearch文档索引API(一) 9.elasticsearch文档索引API(二) 10.elasticsearch文档Get API 11.elasticsearch文档Delete API 12.elasticsearch文档Delete By Query API(一) 13.elasticsearch文档Delete By Query API(二)


Update API

Update API允许开发者根据脚本更新文档,这个操作首先会从索引中获取文档(并行的分片)然后来运行更新脚本,并对结果进行索引(这个操作也可以删除或者忽略),它使用版本控制来确保在“get”和“reindex”期间没有update发生。 需要注意的是,这个操作仍然意味着文档完全重新索引,它只是移除了一些网络往返,并减少了get和reindex之间版本冲突的可能性。需要启用_source该字段才能使此功能正常工作。

例如,有如下一个简单的文档:

代码语言:javascript
复制
curl -X PUT "localhost:9200/test/_doc/1?pretty" -H 'Content-Type: application/json' -d'
{
    "counter" : 1,
    "tags" : ["red"]
}
'
Scripted updates

接下来,可以执行如下请求,给counter增加值,如下:

代码语言:javascript
复制
curl -X POST "localhost:9200/test/_doc/1/_update?pretty" -H 'Content-Type: application/json' -d'
{
    "script" : {
        "source": "ctx._source.counter += params.count",
        "lang": "painless",
        "params" : {
            "count" : 4
        }
    }
}
'

通过ctx可以访问到文档对象,这里的脚本表示给文档的counter字段增加4(即params中定义的值),执行结果如下:

另外,tags是一个集合,也可以像这个集合中动态加入数据,如下:

代码语言:javascript
复制
curl -X POST "localhost:9200/test/_doc/1/_update?pretty" -H 'Content-Type: application/json' -d'
{
    "script" : {
        "source": "ctx._source.tags.add(params.tag)",
        "lang": "painless",
        "params" : {
            "tag" : "blue"
        }
    }
}
'

执行结果如下:

当然,能上能下,既然可以向集合中添加元素,当然也可以从集合中移除元素,例如如下请求,表示文档的tags集合中包含“blue”元素的话,就去获取“blue”元素的下标,然后将之移除:

代码语言:javascript
复制
curl -X POST "localhost:9200/test/_doc/1/_update?pretty" -H 'Content-Type: application/json' -d'
{
    "script" : {
        "source": "if (ctx._source.tags.contains(params.tag)) { ctx._source.tags.remove(ctx._source.tags.indexOf(params.tag)) }",
        "lang": "painless",
        "params" : {
            "tag" : "blue"
        }
    }
}
'

执行结果如下:

除了 _source,ctx也提供了 _index, _type, _id, _version, _routing 以及 _now(当前时间戳)。

也可以向文档中添加字段(注意\u0027是单引号'):

代码语言:javascript
复制
curl -X POST "localhost:9200/test/_doc/1/_update?pretty" -H 'Content-Type: application/json' -d'
{
    "script" : "ctx._source.name = \u0027 江南一点雨 \u0027"
}
'

或者移除字段:

代码语言:javascript
复制
curl -X POST "localhost:9200/test/_doc/1/_update?pretty" -H 'Content-Type: application/json' -d'
{
    "script" : "ctx._source.remove(\u0027tags\u0027)"
}
'

执行结果如下:

而且我们还可以修改要执行的操作,例如如下请求,如果文档中tags集合中包含red,则删除文档,否则不做任何事(noop):

代码语言:javascript
复制
curl -X POST "localhost:9200/test/_doc/1/_update?pretty" -H 'Content-Type: application/json' -d'
{
    "script" : {
        "source": "if (ctx._source.tags.contains(params.tag)) { ctx.op = \u0027delete\u0027 } else { ctx.op = \u0027none\u0027 }",
        "lang": "painless",
        "params" : {
            "tag" : "red"
        }
    }
}
'

执行结果如下:

Updates with a partial document

更新文档API还支持将部分文档合并到现有文档中(简单的递归合并、对象内部合并、替换核心key/value以及数组),要替换整个文档,可以使用前文提到的 index API,如下请求表示向现有文档添加一个新字段:

代码语言:javascript
复制
curl -X POST "localhost:9200/test/_doc/1/_update?pretty" -H 'Content-Type: application/json' -d'
{
    "doc" : {
        "gender" : "男"
    }
}
'

执行结果如下:

如果同时指定doc和script,则doc被忽略,最好是将部分文档的字段对放在脚本本身中。

Detecting noop updates

如果指定doc,将其值与_source合并,默认情况下,如果未做任何更改,将会返回 "result":"noop",如下所示(文档中已经有gender字段了,并且value为男):

代码语言:javascript
复制
curl -X POST "localhost:9200/test/_doc/1/_update?pretty" -H 'Content-Type: application/json' -d'
{
    "doc" : {
        "gender" : "男"
    }
}
'

执行结果如下(注意result字段的值为noop):

可以通过设置 detect_noop来禁用此行为,如下:

代码语言:javascript
复制
curl -X POST "localhost:9200/test/_doc/1/_update?pretty" -H 'Content-Type: application/json' -d'
{
    "doc" : {
        "gender" : "男"
    },
    "detect_noop": false
}
'

执行结果如下:

Upserts

如果文档不存在,则upsert中的元素将被作为一个新文档插入,如果文档已经存在,则script脚本将被执行,如下:

代码语言:javascript
复制
curl -X POST "localhost:9200/test/_doc/1/_update?pretty" -H 'Content-Type: application/json' -d'
{
    "script" : {
        "source": "ctx._source.counter += params.count",
        "lang": "painless",
        "params" : {
            "count" : 4
        }
    },
    "upsert" : {
        "counter" : 1
    }
}
'

执行结果如下:

注意,第一次执行时,由于文档不存在,因此响应的result字段值为“created”,第二次执行时,由于文档已经存在,因此响应值为“updated”。

如果开发者希望无论文档是否存在,都是script执行而不是upsert,那么可以将scripted_upsert设置为true,如下:

代码语言:javascript
复制
curl -X POST "localhost:9200/test/_doc/1/_update?pretty" -H 'Content-Type: application/json' -d'
{
    "scripted_upsert":true,
    "script" : {
        "source": "ctx._source.counter += params.count",
        "lang": "painless",
        "params" : {
            "count" : 4
        }
    },
    "upsert" : {
        "counter" : 1
    }
}
'

也可以使用doc中的值代替upsert中的值(即当文档不存在时,将doc中的值插入),如下:

代码语言:javascript
复制
curl -X POST "localhost:9200/test/_doc/1/_update?pretty" -H 'Content-Type: application/json' -d'
{
    "doc" : {
        "name" : "new_name"
    },
    "doc_as_upsert" : true
}
'
Parameters

在更新操作中,有如下可选参数:

  1. retryonconflict:在get和index之间,可能有其他操作更新了相同的文档,,默认情况下,这时的更新操作将失败,返回一个版本冲突异常,该参数则用来控制在返回异常前的重试次数。
  2. routing:该参数的用法与前面的类似,将更新操作引入到正确的分片上去,如果相关分片并不存在相关文档,则创建新的文档。
  3. timeout:等待一个分片从不可以用变为可用的时间。
  4. waitforactive_shards:与前文类似,这里不再赘述。
  5. refresh:控制本次的变化是否能够被搜索可见。后文我将详细介绍这个参数。
  6. _source:允许控制是否以及如何在响应中返回更新的source。默认情况下,不会返回更新的source。
  7. version:更新API使用Elasticsearch的版本控制以确保文件在更新过程中不会改变,开发者可以使用version参数指定版本,如果文件匹配那么指定的文件需要更新。

注意:更新API不支持外部(版本类型external&external_gte)或强制(版本类型force)版本控制,因为它会导致Elasticsearch版本号与外部系统不同步。

好了,本文先说到这里,有问题欢迎留言讨论。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-01-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 江南一点雨 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Update API
  • Scripted updates
  • Updates with a partial document
  • Detecting noop updates
  • Upserts
  • Parameters
相关产品与服务
Elasticsearch Service
腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档