Elasticsearch painless script not replacing the nested object field value using if condition

冷暖自知 提交于 2019-12-30 10:28:10

问题


I just started with ES and still leaning the tricks of the trade!!! I need to replace/overwrite one of the fields of a nested object type. Here is the sample doc:

{
"name":"db_ref",
"ref_counter":[
    {"ref_name":"test1","count":1},
    {"ref_name":"test2","count":2},
    {"ref_name":"test3","count":3}
    ]
}

Mapping for the above doc :

{
    "settings": {
        "mappings": {
            "test_doc": {
                "properties": {
                    "name": {
                        "type": "string"
                    },
                    "ref_count": {
                        "type": "nested",
                        "ref_name": "string",
                        "count": "long"
                    }
                }
            }
        }
    }
}

I need to update the count field value for a given ref_name. Eg, in the above case, if ref_name is "test1" I want the new count to be 500. I came up with the below painless script for changing the count value, it executes fine without any error but I dont see the value being updated.

curl -XPOST "http://localhost:9200/test_type/test_type/test_db/_update" -d '
{"script": "if (ctx._source.ref_counter.ref_name == cur_ref 
                && ctx._source.ref_counter.count == cur_count)
            {ctx._source.ref_counter.count = new_count };",
"params": {"cur_count": 1,"new_count": 500, "cur_ref": "test1"}}}'

Below is the response:

{"_index":"test_index","_type":"test_type","_id":"test_db","_version":2}

But when I see the document it still has the old values.

Can someone please help me in changing the count value to a new value.


回答1:


I have mentioned the below queries. (Bulk update query and per document update query)

Core piece of logic is in script, which is same in both queries.

I'd suggest you to go through the logic as it's self explainable. Basically the script iterates through the nested document and depending on the condition you've stated, it would update the count accordingly.

Bulk Update - Using _update_by_query

POST <your_index_name>/_update_by_query
{
  "query": {
    "match_all": {}
  },
  "script": {
    "lang": "painless",
    "source": """
    if(ctx._source.ref_counter.contains(params.cur_data)){

      for(int i=0; i<ctx._source.ref_counter.size(); i++)
      {
        HashMap myKV = ctx._source.ref_counter.get(i);
        if(myKV.get(params.key_ref)==params.key_ref_value){
          myKV.put(params.key_count, params.key_count_value_new);
        }
      }

      //ctx._source.ref_counter.add(params.new_data); 

    }""",
    "params": {
      "cur_data": { "ref_name": "test2", "count": 2},
      "new_data": { "ref_name": "test2", "count": 22},
      "key_ref": "ref_name",
      "key_ref_value": "test2",
      "key_count": "count",
      "key_count_value_new": 80

  }}
}

Per Document Update - Using document id

POST <your_index_name>/<your_mapping>/1/_update
{
  "script": {
    "lang": "painless",
    "source": """
    if(ctx._source.ref_counter.contains(params.cur_data)){

      for(int i=0; i<ctx._source.ref_counter.size(); i++)
      {
        HashMap myKV = ctx._source.ref_counter.get(i);
        if(myKV.get(params.key_ref)==params.key_ref_value){
          myKV.put(params.key_count, params.key_count_value_new);
        }
      }

      //ctx._source.ref_counter.add(params.new_data); 

    }""",
    "params": {
      "cur_data": { "ref_name": "test2", "count": 2},
      "new_data": { "ref_name": "test2", "count": 22},
      "key_ref": "ref_name",
      "key_ref_value": "test2",
      "key_count": "count",
      "key_count_value_new": 80

  }
}
}

I hope this helps and let me know if you have any queries!



来源:https://stackoverflow.com/questions/53191009/elasticsearch-painless-script-not-replacing-the-nested-object-field-value-using

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!