zoukankan      html  css  js  c++  java
  • elasticsearch 基础 —— Update API

    Update API

    更新API允许基于提供的脚本更新文档。该操作从索引获取文档(与分片并置),运行脚本(使用可选的脚本语言和参数),并对结果进行索引(也允许删除或忽略操作)。它使用版本控制来确保在“get”和“reindex”期间没有发生更新。

    请注意,此操作仍然意味着文档的完全重新索引,它只是删除了一些网络往返,并减少了get和索引之间版本冲突的可能性。_source需要启用该字段才能使此功能正常工作。

    例如,让我们索引一个简单的文档:

    PUT test/_doc/1
    {
        "counter" : 1,
        "tags" : ["red"]
    }

    Scripted updates 脚本更新

    现在,我们可以执行一个增加计数器的脚本:

    POST test/_doc/1/_update
    {
        "script" : {
            "source": "ctx._source.counter += params.count",
            "lang": "painless",
            "params" : {
                "count" : 4
            }
        }
    }

    我们可以在标签列表中添加一个标签(注意,如果标签存在,它仍会添加它,因为它是一个列表):

    POST test/_doc/1/_update
    {
        "script" : {
            "source": "ctx._source.tags.add(params.tag)",
            "lang": "painless",
            "params" : {
                "tag" : "blue"
            }
        }
    }

    除了_source,下面变量可以通过ctx map来获得:_index, _type, _id, _version, _routing, _parent, 和_now(当前时间戳)

    我们也可以添加一个字段到文档中:

    POST test/_doc/1/_update
    {
        "script" : "ctx._source.new_field = 'value_of_new_field'"
    }

    或者从文档中移除一个字段:

    POST test/_doc/1/_update
    {
        "script" : "ctx._source.remove('new_field')"
    }

    并且,我们甚至可以改变执行的操作。下面这个例子是如果tags字段包含green,就删除文档,否则就什么都不做:

    POST test/_doc/1/_update
    {
        "script" : {
            "source": "if (ctx._source.tags.contains(params.tag)) { ctx.op = 'delete' } else { ctx.op = 'none' }",
            "lang": "painless",
            "params" : {
                "tag" : "green"
            }
        }
    }

    Updates with a partial document 更新部分文档

    更新API还支持传递部分文档,该部分文档将合并到现有文档中(简单的递归合并,对象的内部合并,替换核心“键/值”和数组)。要完全替换现有文档,应使用indexAPI。以下部分更新会向现有文档添加新字段:

    POST test/_doc/1/_update
    {
        "doc" : {
            "name" : "new_name"
        }
    }
    

    如果docscript都指定,那么doc会被忽视掉。最好是将部分文档的字段对放在脚本本身中。

    Detecting noop updates

    如果doc指定,则其值与现有值合并_source。默认情况下,不更改任何内容的更新会检测到它们没有更改任何内容并返回“result”:“noop”,如下所示:

    POST test/_doc/1/_update
    {
        "doc" : {
            "name" : "new_name"
        }
    }

    如果namenew_name请求被发送之前那么整个更新请求被忽略。如果忽略请求,则result返回响应中的元素noop

    {
       "_shards": {
            "total": 0,
            "successful": 0,
            "failed": 0
       },
       "_index": "test",
       "_type": "_doc",
       "_id": "1",
       "_version": 6,
       "result": "noop"
    }

    您可以通过设置“detect_noop”来禁用此行为:false,如下所示:

    POST test/_doc/1/_update
    {
        "doc" : {
            "name" : "new_name"
        },
        "detect_noop": false
    }

    Upserts

    如果文档尚不存在,则upsert元素的内容将作为新文档插入。如果文档确实存在,那么 script将执行:

    POST test/_doc/1/_update
    {
        "script" : {
            "source": "ctx._source.counter += params.count",
            "lang": "painless",
            "params" : {
                "count" : 4
            }
        },
        "upsert" : {
            "counter" : 1
        }
    }

    scripted_upsert

    如果您希望脚本运行,无论文档是否存在 - 即脚本处理初始化文档而不是 upsert元素 - 然后设置scripted_upserttrue

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

    doc_as_upsert

    设置doc_as_upserttrue,如果没有文档,则doc就是新的文档

    POST test/_doc/1/_update
    {
        "doc" : {
            "name" : "new_name"
        },
        "doc_as_upsert" : true
    }

    参数

    更新操作支持以下查询字符串参数:

    参数名 描述
    retry_on_conflict 在查询和插入阶段更新时,很有可能其他进程在此之前更新同一个文档。默认情况下,此处更新将会失败并且会抛出版本冲突异常。retry_on_conflict参数控制在最终抛出异常之前,重试更新多少次
    routing 如果更新的文档不存在,那么就会根据routing将更新请求路由到正确的分片上并且将routing设置给upsert请求。已存在的文档不能更新路由(routing
    parent 如果更新的文档不存在,那么就会根据parent将更新请求路由到正确的分片上并且将parent设置给upsert请求。已存在的文档不能更新parent。如果给索引(数据库)路由指定了别名,那么该别名会覆盖parent路由,并且会被用于路由请求。
    timeout 分片变为可利用之前的等待超时时间
    wait_for_active_shards 在处理更新请求操作之前,副本分片必须存活的数量。详情参考这里
    refresh 控制此处请求做出的更改对于搜索而已是可见的。参考?refresh
    _source 在响应中控制是否和如何控制更新返回的source字段。默认情况下,更新的source是不返回的。详情查看source filtering
    version&version_type update api使用elasticsearch内部版本号,来确保在更新期间,文档没有变化。你也可以使用version参数来指定版本号,只有和指定版本号匹配的情况下才会更新。通过将version type设置为force,你可以在更新文档后,强制新版本号(使用时非常小心,使用force不能确保文档没有发生变化,通俗点就是会忽略版本冲突)。

    The update API does not support external versioning

    update api 是不支持外部版本号(version types external & external_gte)的,因为它会造成elasticsearch版本号和外部系统不一致。可以使用index api进行替换。

  • 相关阅读:
    Docker 常用命令
    SpringMVC Controller 返回值几种类型
    SSM框架整合(IntelliJ IDEA + maven + Spring + SpringMVC + MyBatis)
    SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
    springmvc 自定义拦截器实现未登录用户的拦截
    使用idea搭建SSM框架
    详解intellij idea搭建SSM框架(spring+maven+mybatis+mysql+junit)(下)
    IntelliJ IDEA maven项目new里没有package
    ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' (using password: NO) ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' (using password: YES)
    MySql 5.7密码查看或修改
  • 原文地址:https://www.cnblogs.com/gmhappy/p/11864056.html
Copyright © 2011-2022 走看看