es,其实是有个内置的脚本支持的,可以基于groovy脚本实现各种各样的复杂操作
    基于groovy脚本,如何执行partial update
    es scripting module,我们会在高手进阶篇去讲解,这里就只是初步讲解一下

    1. PUT /test_index/_doc/11
    2. {
    3. "num": 0,
    4. "tags": []
    5. }

    (1)内置脚本

    POST /test_index/_update/11
    {
      "script":{
        "source": "ctx._source.num+=1"
      }
    }
    
    {
      "_index": "test_index",
      "_type": "test_type",
      "_id": "11",
      "_version": 2,
      "found": true,
      "_source": {
        "num": 1,
        "tags": []
      }
    }
    

    (2)外部脚本
    在 ES 的 HOME 目录的 config 目录下的 scripts 目录中创建 groovy 脚本
    test-add-tags.groovy 脚本文件内容如下:

    ctx._source.tags+=new_tag
    
    POST /test_index/_update/11
    {
      "script": {
        "lang": "groovy",           #指定脚本语言
        "file": "test-add-tags",    #指定脚本文件名
        "params": {
          "new_tag": "tag1"
        }
      }
    }
    

    报错如下:

    {
      "error" : {
        "root_cause" : [
          {
            "type" : "x_content_parse_exception",
            "reason" : "[4:5] [script] unknown field [file]"
          }
        ],
        "type" : "x_content_parse_exception",
        "reason" : "[4:12] [UpdateRequest] failed to parse field [script]",
        "caused_by" : {
          "type" : "x_content_parse_exception",
          "reason" : "[4:5] [script] unknown field [file]"
        }
      },
      "status" : 400
    }
    

    有可能是没有安装 groovy 插件。
    (3)用脚本删除文档
    脚本内容:

    ctx.op = ctx._source.num == count ? 'delete' : 'none'
    
    POST /test_index/_update/11
    {
      "script": {
        "lang": "groovy",
        "file": "test-delete-document",
        "params": {
          "count": 1
        }
      }
    }
    

    (4)upsert操作

    POST /test_index/_update/11
    {
      "doc": {
        "num": 1
      }
    }
    
    {
      "error": {
        "root_cause": [
          {
            "type": "document_missing_exception",
            "reason": "[_doc][11]: document missing",
            "index_uuid": "6m0G7yx7R1KECWWGnfH1sw",
            "shard": "4",
            "index": "test_index"
          }
        ],
        "type": "document_missing_exception",
        "reason": "[_doc][11]: document missing",
        "index_uuid": "6m0G7yx7R1KECWWGnfH1sw",
        "shard": "4",
        "index": "test_index"
      },
      "status": 404
    }
    

    如果指定的document不存在,就执行upsert中的初始化操作;如果指定的document存在,就执行doc或者script指定的partial update操作

    POST /test_index/_update/11
    {
       "script" : "ctx._source.num+=1",
       "upsert": {
           "num": 0,
           "tags": []
       }
    }
    

    注: 高版本的elasticsearch不支持file类型,也就是说不支持从外部文件读取脚本。

    1. 需要先将脚本post到es的库中 ``` POST /_scripts/test-add-tags { “script”:{ “lang”:”painless”, “source”:”ctx._source.tags=params.new_tag” } }
    tags 是数组,不能使用 `+=`
    
    2. 根据id来调用
    

    POST /test_index/_update/11 { “script”:{ “id”:”test-add-tags”, “params”:{ “new_tag”:[“dddddddd”] } } }

    ``` 注:ES6.x 移除了对 groovy script 脚本的支持,因为 groovy script 存在内存泄漏的问题。