11、Update API

原文地址:https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html#_updates_with_a_partial_document

elasticsearch版本:6.5

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

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

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

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

(1)Scripted updates

下面的请求将增加counter字段的值:

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

下面增加 一个tag到tags:

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

下面可以移除tags里面的tag,注意painless的remove函数是需要你删除的tag的index,因此你需要想办法获取它来避免运行时出错。注意:如果要删除的tag在tags里面出现多次,但是只会删除一次。

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

除了_source,ctx的下面这些值也可以用:_index,_type,_id,_version,_routing和_now。

我们也可以这样添加一个字段:

扫描二维码关注公众号,回复: 4812757 查看本文章
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')"
}

我们甚至可以指定ctx的操作,如下,判断tags是否包含green,如果包含则删除文档,否则不进行任何操作:

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

(2)Updates with a partial document

update API也支持将部分文档合并到现有文档中(简单的递归合并,对象的属性合并、替换属性值和数组)。要完全替换现有的文档,应使用index API。一下的部分更新将向现有文档中添加新的字段:

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

如何both和script同时存在,那么doc将会被忽略。

(3)Detecting noop updates

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

PUT test/_doc/1/_update
{
    "doc":{
        "name":"new _name"
    }
}

如何name在更新前就是new_name,那么这个请求将会被忽略。返回值result的值将是noop:

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

您可以禁止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

如何您想只是script不管文档是否存在,那么设置scripted_upsert为true:

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_upsert设置为true,将会把doc中的值按照upsert执行:

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

猜你喜欢

转载自blog.csdn.net/mine_1/article/details/85697303
今日推荐