elasticsearch notes-006-document API-CRUD-single document update operation

[toc]

1. Single document Update API

update API updates the document according to the provided script; Get the document from the index, execute the script, and index the new results

How do I ensure that no updates occur during get and reindex? -- > Use version control;

This operation still means a complete re index of the document. It only removes some network round-trip loss and reduces the chance of version conflict between get and index

1. script update: numerical calculation

Example: create a new document to test index, and then modify counter=counter+4; Then add a blue color for tags:

#1. Create a document to test index
PUT test/_doc/1
{
    "counter" : 1,
    "tags" : ["red"]
}

Add the value of "counter" to the given parameter:

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

View current: GET test/_source/1

{
    "counter" : 5,
    "tags" : [
      "red"
    ]
}

Similarly: counter=counter*2:

POST test/_update/1
{
  "script": {
    "source": "ctx._source.counter *= params.val",
    "params": {
      "val": 2
    }
  }
}

2. script update: Add / delete array (set)

2.1 add a yellow:

POST test/_update/1
{
  "script": {
    "source": "ctx._source.tags.add(params.clr)",
    "params": {"clr": "yellow"}
  }
}

output:

{
    "counter" : 10,
    "tags" : [
      "red",
      "yellow"
    ]
}

2.2 delete (note index)

In fact, it is the method of ArrayList!

POST test/_update/1
{
  "script": {
    "source": "ctx._source.tags.remove(params.val)",
    "params": {
      "val": 0
    }
  }
}
{
    "counter" : 10,
    "tags" : [ "yellow" ]
}

2.3 clear

Similarly, you can call other methods of ArrayList, such as:

POST test/_update/1
{
  "script": {
    "source": "ctx._source.tags.clear()"
  }
}

2.4 how to delete matching content

If now tags = ["yellow", "red", "blue"], to delete "red", according to the content rather than the index:

POST test/_update/1
{
  "script": {
    "source": "if (ctx._source.tags.contains(params.val)) {ctx._source.tags.remove(ctx._source.tags.indexOf(params.val));}",
    "params": {
      "val": "red"
    }
  }
}

GET test/_source/1 output:

{
    "counter" : 10,
    "tags" : [
      "yellow",
      "blue"
    ]
}

Note: script ";" in source Can not;

2.5 script update: other built-in variables of ctx

Except_ In addition to source, ctx mapping also provides the following variables:_ index,_ type,_ id,_ version,_ routing and_ Now (current timestamp).

2.6 script update: Add / delete field entry

We add a new field to document 1 in the test index: "addr": "beijing":

# update add field entry
POST test/_update/1
{
  "script": {
    "source": "ctx._source.addr='beijing'"
    }
}
# Add another one
POST test/_update/1
{
  "script": {
    "source": "ctx._source.location='yizhuang'"
    }
}

GET test/_source/1

{
  "counter" : 10,
  "tags" : [
    "yellow"
  ],
  "addr" : "beijing",
  "location" : "yizhuang"
}

Delete:

# update delete field
POST test/_update/1
{
  "script": {
    "source": "ctx._source.remove('location')"
  }
}

GET test/_source/1 :

{
  "counter" : 10,
  "tags" : [
    "yellow"
  ],
  "addr" : "beijing"
}

3. doc new fields:

In addition to using script, you can also use doc to add fields; If there are both, an error will be reported!

POST test/_update/1
{
    "doc" : {
        "loc" : "yz"
    }
}
{
  "counter" : 10,
  "tags" : [
    "yellow"
  ],
  "addr" : "beijing",
  "loc" : "yz"
}

If doc is specified, its value will be the same as the existing one_ source consolidation; If the doc is executed many times and the data does not change\_ version and\_ seq\_no will be updated! "result" : "noop"

4. upsert update + insert

4.1 script+upsert mode

If the document does not already exist, the contents of the upsert element will be inserted as a new document. If the document exists, execute the script:

DELETE test/_doc/2 let's do this first to delete the document with id=2; Then perform the following upsert operations:

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

Because there is no document with id=2 at the moment, there will be no default + = operation; In this way, the content in upsert will be saved as the content of the document;

This is to repeat the above upsert operation once!! Re check result: GET test/_source/2

{
  "counter" : 6,
  "name" : "ifnotexists"
}

You can see that counter is 2 + 4;

4.2 doc based upsert

The doc method can also implement upsert as follows: if it is simply based on the document with id=2 above, execute the following:

POST test/_update/2
{
  "doc": {
    "gender": "male"
  },
  "doc_as_upsert": true
}

Just added a gender field!

{
  "counter" : 6,
  "name" : "ifnotexists",
  "gender" : "male"
}

Now delete the document: DELETE test/_doc/2, it will appear as the function of upsert. At this time, GET test/_source/2:

{"gender" : "male"}

5. Other parameters of update

timeout/wait_for_active_shards/version, and if_seq_no + if_primary_term

5.1 if_seq_no+if_primary_term

POST test/_update/2?if_seq_no=31&if_primary_term=1
{
  "script": {
    "source": "ctx._source.counter=params.val",
    "params": {
      "val": 3
    }
  }
}

If_ seq_no and_ primary_ If the term matches, the update will be executed, otherwise an error will be reported!

2. TODO: Update By Query API

Tags: ElasticSearch

Posted by tdors on Fri, 06 May 2022 05:41:57 +0300