case by case系列:ES update schema不存在的字段是否会返回noop

结论

不会,只要source数据发生变化,update就会触发,即使索引schema中不存在这个字段

背景

ES每次更新都会标记删除一个doc,然后新增一个doc,随着时间推移从而产生大量 is_deleted 标记删除的doc,影响查询性能;merge可以清理大部分,但毕竟是异步的,而且受到很多限制,实际生产中高频update场景会有大量的 is_deleted 文档存在。这也是ES不适合高频更新场景的原因。

对于update,我们自然希望是越少越好,并且如果数据没有变化,我们也希望update返回noop,不执行这个update操作,而不是直接无脑的覆盖更新。

假设一个场景:schema中不存在某个字段,比如典型的 update_time 字段,schema中不存在,但每次update,这个字段的数据都会变化,是否会执行一次更新?或者由于schema中不存在而直接返回noop?

测试

schema:

复制代码
PUT zmc_x1
{
  "aliases": {},
  "mappings": {
    "dynamic": "false",
    "properties": {
      "id": {
        "type": "keyword"
      }
    }
  }
}

写入一条数据

复制代码
POST zmc_x1/_doc/1
{
  "id": "111"
}

执行更新:有script的情况下每次都覆盖更新

复制代码
POST zmc_x1/_update/1
{
  "script" : {
    "source": "ctx._source.id = params.id",
    "lang": "painless",
    "params" : {
      "id" : "111"
    }
  }
}

正常更新schema中存在的字段,数据没有变化,返回noop(不执行更新)

name字段在schema中不存在,更新name字段,依然会触发update