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