美文网首页大数据&云计算Elasticsearch实践与分析系统运维专家
Elasticsearch写入时既要upsert又要实现部分更新

Elasticsearch写入时既要upsert又要实现部分更新

作者: bellengao | 来源:发表于2022-01-21 11:27 被阅读0次

    背景

    客户为了实现search after功能,必须有一个modify_at字段在更新doc的时候不能修改,也就是更新的时候如果请求body里包含了这个modify_at字段,就不更新;但是同时又要保证upsert功能,在没有该文档的时候,就新增该文档。

    梳理一下,客户的需求就是在upsert的同时,实现部分更新。

    实现方式

    部分更新文档的话就需要通过[update API] (https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html) 实现,通过指定文档id来实现部分更新,部分更新可以通过plainless script或者指定doc字段来实现

    另外,update API 可以实现upsert功能,在body中指定upsert字段来实现。
    综上,最终通过如下方式解决了客户的需求:

    • 第一次写入,POST my_index/_update/1
      通过script脚本实现部分更新,以及指定upsert功能在文档1不存在时就插入:
    {
      "script": {
        "source": "ctx._source.a = params.a;ctx._source.b = params.b;",
        "lang": "painless",
        "params": {
          "a": 1,
          "b": 1
        }
      },
      "upsert": {
        "a": 1,
        "b": 1,
        "modify_at": 1634819527790
      }
    }
    

    或者通过指定doc字段实现部分更新:

    {
      "doc": {
        "a": 1,
        "b": 1
      },
      "upsert": {
        "a": 1,
        "b": 1,
        "modify_at": 1634819527790
      }
    }
    
    • 查看写入结果, GET my_index/_doc/1
    {
      "_index": "x",
      "_id": "1",
      "_version": 1,
      "_seq_no": 12,
      "_primary_term": 1,
      "found": true,
      "_source": {
        "a": 1,
        "b": 1,
        "modify_at": 1634819527790
      }
    }
    
    • 后续更新,方式和第一次写入相同,只不过传值不同,客户端对是要插入还是更新无感
    {
      "script": {
        "source": "ctx._source.a = params.a;ctx._source.b = params.b;",
        "lang": "painless",
        "params": {
          "a": 2,
          "b": 2
        }
      },
      "upsert": {
        "a": 2,
        "b": 2,
        "modify_at": 1634819527790
      }
    }
    

    或者

    {
      "doc": {
        "a": 2,
        "b": 2
      },
      "upsert": {
        "a": 1,
        "b": 1,
        "modify_at": 1634819527790
      }
    }
    
    
    • 获取结果,GET my_index/_doc/1
    {
      "_index": "x",
      "_id": "1",
      "_version": 2,
      "_seq_no": 13,
      "_primary_term": 1,
      "found": true,
      "_source": {
        "a": 2,
        "b": 2,
        "modify_at": 1634819527790
      }
    }
    
    

    相关文章

      网友评论

        本文标题:Elasticsearch写入时既要upsert又要实现部分更新

        本文链接:https://www.haomeiwen.com/subject/nyjehrtx.html