Безболезненный скрипт Elasticsearch не заменяет значение поля вложенного объекта, используя условие if - PullRequest
0 голосов
/ 07 ноября 2018

Я только начал с ES и все еще пользуюсь уловками торговли !!! Мне нужно заменить / переписать одно из полей типа вложенного объекта. Вот пример документа:

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

Отображение для вышеупомянутого документа:

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

Мне нужно обновить значение поля count для данного ref_name. Например, в приведенном выше случае, если ref_name равно " test1 ", я хочу, чтобы новый count был 500 . Я предложил приведенный ниже безболезненный скрипт для изменения значения count , он прекрасно работает без каких-либо ошибок, но я не вижу, чтобы значение обновлялось.

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"}}}'

Ниже приведен ответ:

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

Но когда я вижу документ, он все еще имеет старые значения.

Может кто-нибудь помочь мне перевести значение счетчика на новое значение.

1 Ответ

0 голосов
/ 07 ноября 2018

Я упомянул следующие запросы. (Bulk update запрос и per document запрос на обновление)

Основная часть логики находится в script, что одинаково в обоих запросах.

Я бы посоветовал вам пройти через логику, так как она самоочевидна. По сути, скрипт выполняет итерацию по вложенному документу и, в зависимости от указанного вами условия, обновляет count соответственно.

Массовое обновление - Использование _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

  }}
}

Обновление документа - с использованием идентификатор документа

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

  }
}
}

Я надеюсь, что это поможет, и дайте мне знать, если у вас есть какие-либо вопросы!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...