• ElasticSearch API 之 UPDATE


    ES本身是一个倾向于查询检索的框架,对于更新的操作,太过频繁总归不好的。
    阅读本篇后,你可以使用Script对所有的文档执行更新操作,也可以使用doc对部分文档执行更新,也可以使用upsert对不存在的文档执行添加操作。

    参考:http://www.cnblogs.com/xing901022/p/5330778.html

    更新

    更新操作允许ES获得某个指定的文档,可以通过脚本等操作对该文档进行更新。

    可以把它看成是先删除再索引的原子操作,只是省略了返回的过程,这样即节省了来回传输的网络流量,也避免了中间时间造成的文档修改冲突。

    下面例子,查找id为25的文档:

    curl -XGET localhost:9200/bank/account/25?pretty{
    • "_index""bank",
    • "_type""account",
    • "_id""25",
    • "_version"1,
    • "found"true,
    • "_source": {
      • "account_number"25,
      • "balance"40540,
      • "firstname""Virginia",
      • "lastname""Ayala",
      • "age"39,
      • "gender""F",
      • "address""171 Putnam Avenue",
      • "employer""Filodyne",
      • "email""virginiaayala@filodyne.com",
      • "city""Nicholson",
      • "state""PA"
      }
    }

    脚本更新

    Es支持通过脚本更改文档的信息:

    curl -XPOST 'localhost:9200/bank/account/25/_update' -d '{
        "script" : {
            "inline": "ctx._source.age += number",
            "params" : {
                "number" : 5
            }
        }
    }'结果报错:{
    • "error": {
      • "root_cause": [
        • {
          • "type""remote_transport_exception",
          • "reason""[lihao][127.0.0.1:9300][indices:data/write/update[s]]"
          }
        ],
      • "type""illegal_argument_exception",
      • "reason""failed to execute script",
      • "caused_by": {
        • "type""script_exception",
        • "reason""scripts of type [inline], operation [update] and lang [groovy] are disabled"
        }
      },
    • "status"400
    } 报错原因:  在最新版本的Elasticsearch中,基于安全考虑(如果用不到,请保持禁用),默认禁用了动态脚本功能。完全开启动态脚本功能 script.inline: on script.indexed: on script.file: on 重启ES

    {

    • "_index""bank",
    • "_type""account",
    • "_id""25",
    • "_version"2,
    • "_shards": {
      • "total"2,
      • "successful"1,
      • "failed"0
      }
    }

    curl -XGET localhost:9200/bank/account/25?pretty
    {
      "_index" : "bank",
      "_type" : "account",
      "_id" : "25",
      "_version" : 2,
      "found" : true,
      "_source" : {
        "account_number" : 25,
        "balance" : 40540,
        "firstname" : "Virginia",
        "lastname" : "Ayala",
        "age" : 44,
        "gender" : "F",
        "address" : "171 Putnam Avenue",
        "employer" : "Filodyne",
        "email" : "virginiaayala@filodyne.com",
        "city" : "Nicholson",
        "state" : "PA"
      }
    }

    上面就是通过参数来为age加5.

    除了_source字段,可以通过ctx来获得_index_type_id_version_parent_timestamp_ttl等字段信息。

    也可以添加某个字段:

    curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
        "script" : "ctx._source.name_of_new_field = "value_of_new_field""
    }'

    移除字段:

    curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
        "script" : "ctx._source.remove("name_of_field")"
    }'

    也支持稍微复杂点的操作,逻辑判断,比如根据某个标记执行不同的操作。比如如果有blue这个标记,则删除该文档;否则什么也不做:

    curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
        "script" : {
            "inline": "ctx._source.tags.contains(tag) ? ctx.op = "delete" : ctx.op = "none"",
            "params" : {
                "tag" : "blue"
            }
        }
    }'

    只更新部分文档

    上面的脚本是对所有的文档都起作用,这里讲解下如何只对部分文档进行修改。使用doc可以实现简单的递归合并、内部合并、替换KV以及数组。

    curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
        "doc" : {
            "name" : "new_name"
        }
    }'

    如果同时使用了doc和script,那么doc的操作会自动忽略。因此最好是把特殊的操作也放在脚本中。

    更新检测

    如果使用doc,那么会自动合并到现有的文档中。如果doc中定义的部分与现在的文档相同,则默认不会执行任何动作。设置detect_noop=false,就会无视是否修改,强制合并到现有的文档。

    curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
        "doc" : {
            "name" : "new_name"
        },
        "detect_noop": false
    }'

    上面的例子中,如果name字段为new_name,无论当前的文档是否与doc中定义的相同,都会把doc合并到文档中。

    upsert插入

    这个参数主要用于当文档不存在时,ES的操作。

    curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
        "script" : {
            "inline": "ctx._source.counter += count",
            "params" : {
                "count" : 4
            }
        },
        "upsert" : {
            "counter" : 1
        }
    }'

    在上面的例子中,当文档存在时,执行脚本;当文档不存在时,upsert中的内容就会插入到对应的文档中。

    如果你想无论文档是否存在都执行脚本操作,那么可以使用参数scripted_upsert为true。

    curl -XPOST 'localhost:9200/sessions/session/dh3sgudg8gsrgl/_update' -d '{
        "scripted_upsert":true,
        "script" : {
            "id": "my_web_session_summariser",
            "params" : {
                "pageViewEvent" : {
                    "url":"foo.com/bar",
                    "response":404,
                    "time":"2014-01-01 12:32"
                }
            }
        },
        "upsert" : {}
    }'

    相对于之前的使用Upsert中的内容添加到不存在的文档,使用doc_as_upsert可以在文档不存在的时候,把doc中的内容插入到文档中。

    curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
        "doc" : {
            "name" : "new_name"
        },
        "doc_as_upsert" : true
    }'
  • 相关阅读:
    一个丰富的通知工具类 --第三方开源--NotifyUtil
    RecycleView出现折叠效果--第三方开源--SectionedExpandableGridRecyclerView
    Socket TCP连接相互通信
    InputStream与String,Byte之间互转
    socket调试工具
    可直接导入studio的 android-Ultra-Pull-To-Refresh-master
    纯手写验证码MVC中
    Upload图片-单张
    C#、SQL中的事务
    MVC、控件、一般处理程序中的session and cookie
  • 原文地址:https://www.cnblogs.com/pilihaotian/p/8823131.html
Copyright © 2020-2023  润新知