Update only specific field value in elasticsearch
Asked Answered
S

9

114

Is it possible to update some specific fields value in elasticsearch with out overwriting other fields. ?

Sapowith answered 24/10, 2013 at 10:20 Comment(1)
yes thanks for the help.I have used script format and followed update apiSapowith
B
90

As a codebased contribution to this answer, the following query may be used:

POST /index/type/100100471/_update
{
    "doc" : {
        "yourProperty" : 10000
    }
}

This query updates yourProperty property only.

As a result, this response appears:

{
   "_index": "index",
   "_type": "type",
   "_id": "100100471",
   "_version": 1,
   "_shards": {
      "total": 0,
      "successful": 1,
      "failed": 0
   }
}
Bombe answered 6/11, 2016 at 16:38 Comment(2)
I am getting Validation Failed: 1: script or doc is missing; - any idea why?Eparch
@Eparch The new syntax without types is POST /yourindexname/_update/youridnumber { "doc" : { "yourProperty" : 10000 } }Eady
W
90

In ES 7.3 the new format is:

POST /myindex/_update/mydocid
{
    "doc" : {
        "myfield": "new value of my field"
    }
}
Worrywart answered 27/8, 2019 at 14:2 Comment(0)
Y
29

Yes, Elasticsearch supports partial updates. That means that you can submit:

  • a partial document, which will be merged with the existing one
  • a script that will be executed on top of the existing document

Have a look at the update api. In both cases, what happens under the hood, due to how the underlying lucene library works, is that the document to be updated is retrieved, the changes are applied to it, and the old document gets overwritten with the new. At the end of the day it is in fact a complete rewrite of the document, but you don't have to submit the whole document, unless you disabled the _source field, enabled by default, which is the field that allows you to retrieve to whole document in order to apply changes to it.

Yolandoyolane answered 25/10, 2013 at 7:6 Comment(3)
As a continue could you take a look at this question #28938446Collis
"If both doc and script are specified, then doc is ignored. If you specify a scripted update, include the fields you want to update in the script." elastic.co/guide/en/elasticsearch/reference/current/…Kingcup
@Yolandoyolane If the script checks some other document fields to update, will the script always see the latest data even if those fields haven't been refreshed for searching?Stearn
M
11

If you would like to update the existing field value only then you must try this solution:

POST IndexName/_update_by_query
{
  "script": {
    "source": """

   if (ctx._source?.Field != null) 
    {  
        ctx._source.remove('Field');
        ctx._source.put('Field', 'Value');
    }   
    """,
    "lang": "painless"
  },
  "query": {
    "terms": {
        "_id": [
          1 (Replace with Document ID)
        ]
      }
  }
}

If you would like to add new field with value then you must try this solution:

POST IndexName/_update_by_query
{
  "script": {
    "source": """

   if (ctx._source?.NewField == null) 
    {  
        ctx._source.hf.put('NewField', 'Value');
    }   
    """,
    "lang": "painless"
  },
  "query": {
    "terms": {
        "_id": [
          1 (Replace with Document ID)
        ]
      }
  }
}
Moraceous answered 14/2, 2019 at 7:16 Comment(3)
I need help to use Api Update in elasticsearch, the problem is what I have when I want to update this level further inside the structure, for example: { "mainLevel": [ { "name": "maxi", "SecundaryLevel": [ { "title": "Bachelor" } ] } ] } In this case the update would like to do it in "SecondaryLevel" but for a certain "MainLevel", I leave my index below.Jakejakes
Max you can see my below comment. So this way if you do POST /foo_v1/_bulk?pretty=true&error_trace=true {"update":{"_index":"foo_v1","_type":"footype","_id":"397"}} {"doc":{"SecundaryLevel":{"title":"Married","EmailId":"[email protected]"}} So this query will only update the "SecondaryLevel" object in doc and for specific id. I hope this answers your question. Sorry for late reply, I missed your comment earlier.Moraceous
how is it possible to use this script in chrome extension head?Pruter
S
10

Update By Query API

Updates documents that match the specified query. If no query is specified, performs an update on every document in the data stream or index without modifying the source, which is useful for picking up mapping changes.

POST http://localhost:9200/INDEX_NAME/_update_by_query
{
  "script": {
    "source": "ctx._source.userName=new_user_name",
    "lang": "painless"
  },
  "query": { 
    "term": {
      "userName": "old_user_name"
    }
  }
}   

In the above example, the userName field value will be updated to new_user_name

Seleta answered 7/5, 2021 at 6:46 Comment(0)
M
5

Also you can use bulk Update to partially update multiple doc

POST /foo_v1/_bulk?pretty=true&error_trace=true
{"update":{"_index":"foo_v1","_type":"footype","_id":"397"}}
{"doc":{"Name":"foo","EmailId":"[email protected]"}}
{"update":{"_index":"foo_v1","_type":"footype","_id":"398"}}
{"doc":{"Name":"foo1","EmailId":"[email protected]"}}

If you are not sure whether it will be a update or insert like Upsert so you can do :

POST /foo_v1/_bulk?pretty=true&error_trace=true
{"update":{"_index":"foo_v1","_type":"footype","_id":"397"}}
{"doc":{"Name":"foo","EmailId":"[email protected]"}, "doc_as_upsert" : true}

use "doc_as_upsert" : true

Moraceous answered 18/11, 2020 at 8:29 Comment(0)
E
5

Make POST call to {{host}}/{{index}}/_doc/{{id}}/_update

with body as

{
    "doc": {
        "field": "value"
    }
}

Output would be similar to

{
    "_index": "{{index}}",
    "_type": "_doc",
    "_id": "{{id}}",
    "_version": 3,
    "result": "updated",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 27,
    "_primary_term": 2
}
Exposition answered 18/11, 2021 at 17:16 Comment(1)
The end of this URL should be ...{{index}}/_update/1. Your alternative still works with ES 7 but everything involving the "_doc" endpoint will become illegal with ES 8! Marc's answer here in 2019 already gave the future-proof answer. You should delete yours.Abdication
R
2

Try this

curl -XPOST --header 'Content-Type: application/json' https://search-testarticle-2cwv6oh7wtz3hxowgxv3rprnsa.ap-south-1.es.amazonaws.com/test/_update/4gI4knQB7d5sAgV24YPy -d '{
"doc":  { "name" : "Ankit Singh Raj" }
}'
Rosati answered 15/9, 2020 at 16:26 Comment(0)
N
0

For me, this worked:

    POST /jira_project/_doc/4c459bbb-8cc2-44c0-a455-f01cfc658017/_update
    {
      "doc":{
        "body": {
          "isDeleted": true,
          "deletedAt": "2023-10-03T11:16:21.489Z"
        }
      }

    }

Explanation:

  1. Here "jira_project" is the index name.
  2. "_doc" is the type of entity you are targeting within that index (this is deprecated in newer versions since by default entities within an index are taken as doc type).
  3. I have updated some keys inside the "body" key, so that's why I mentioned "body" while updating.

Everything else is self-explanatory.

Nationalize answered 12/1 at 7:2 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Chancellor

© 2022 - 2024 — McMap. All rights reserved.