Elasticsearch 文档更新操作

正如我们提到的,文档不能被修改,它们只能被替换掉。更新API也必须遵循这一法则。从表面看来,貌似是文档被替换了。对内而言,它必须按照找回-修改-索引的流程来进行操作与管理。不同之处在于这个流程是在一个片(shard) 中完成的,因此可以节省多个请求所带来的网络开销。除了节省了步骤,同时我们也能减少多个进程造成冲突的可能性。

使用更新请求最简单的一种用途就是添加新数据。新的数据会被合并到现有数据中,而如果存在相同的字段,就会被新的数据所替换。例如我们可以为我们的employee添加tags和views字段:
curl -XPOST "http://localhost:9200/megacorp/employee/1/_update" -d '
{
    "doc" : {
      "tags" : [ "testing" ],
      "views": 0
   }
}'

如果请求成功,我们就会收到一个类似于索引时返回的内容:

{
    "_index": "megacorp",
    "_type": "employee",
    "_id": "1",
    "_version": 21,
    "result": "updated",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    }
}

再次取回数据,你可以在_source中看到更新的结果:

{
  "_index" : "megacorp",
  "_type" : "employee",
  "_id" : "1",
  "_version" : 21,
  "found" : true,
  "_source" : {
    "first_name" : "John",
    "last_name" : "Aires",
    "age" : 24,
    "about" : "I love to go rock climbing",
    "interests" : [
      "sports",
      "food"
    ],
    "views" : 0,
    "tags" : [
      "testing"
    ]
  }
}
新的数据已经添加到了字段_source中。

更新一篇可能不存在的文档

想象一下,我们可能需要在Elasticsearch中存储一个页面计数器。每次用户访问这个页面,我们就增加一下当前页面的计数器。但是如果这是个新的页面,我们不能确保这个计数器已经存在。如果我们试着去更新一个不存在的文档,更新操作就会失败。

为了防止上述情况的发生,我们可以使用upsert参数来设定文档不存在时,它应该被创建:
curl -XPOST "http://localhost:9200/megacorp/employee/1/_update" -d '
{
   "script" : "ctx._source.views+=1",
   "upsert": {
       "views": 1
   }
}'
首次运行这个请求时,upsert的内容会被索引成新的文档,它将views字段初始化为1。当之后再请求时,文档已经存在,所以脚本更新就会被执行,views计数器就会增加。

更新和冲突

在本节的开篇我们提到了当取回与重新索引两个步骤间的时间越少,发生改变冲突的可能性就越小。但它并不能被完全消除,在更新的过程中还可能存在另一个进程进行重新索引的可能性。

为了避免丢失数据,更新API会在获取步骤中获取当前文档中的_version,然后将其传递给重新索引步骤中的索引请求。如果其他的进程在这两部之间修改了这个文档,那么_version就会不同,这样更新就会失败。

对于很多的局部更新来说,文档有没有发生变化实际上是不重要的。例如,两个进程都要增加页面浏览的计数器,谁先谁后其实并不重要 —— 发生冲突时只需要重新来过即可。

你可以通过设定retry_on_conflict参数来设置自动完成这项请求的次数,它的默认值是0。
curl -XPOST "http://localhost:9200/megacorp/employee/1/_update?retry_on_conflict=5 <1>" -d '
{
   "script" : "ctx._source.views+=1",
   "upsert": {
       "views": 0
   }
}
失败前重新尝试5次

这个参数非常适用于类似于增加计数器这种无关顺序的请求,但是还有些情况的顺序就是很重要的。例如上一节提到的情况,你可以参考乐观并发控制以及悲观并发控制来设定文档的版本号。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值