Обновите документы ElasticSearch, соответствующие определенным критериям

Я хочу массово обновить документы, соответствующие критериям.
Версия ES: 5.1.1
Индекс: index_1234
Тип: адреса
URL: POST http://localhost:9200/index_1234/addresses/_update_by_query
Полезная нагрузка:

{
    "id":1,
    "address":"temp address"
}

Я использую следующий встроенный скрипт для обновления документов

{
  "script": {
     "inline": "if(ctx._source.containsKey(\"address\") && ctx._source.address == "temp address"){ctx._source.address='perm address'}"
  }
}

т.е. если поле «адрес» имеет значение «временный адрес», я заменяю его «постоянным адресом».

Этот скрипт работает отлично и обновляет только соответствующие документы. Однако у меня есть сомнения

Предположим, что всего 10 документов, из которых 5 имеют поле «адрес» как «временный адрес» и 5 имеют поле «адрес» как «постоянный адрес».

При выполнении вышеуказанного скрипта он дает следующее o/p

{
    "took": 131,
    "timed_out": false,
    "total": 10,
    **"updated": 10**,
    "deleted": 0,
    "batches": 1,
    "version_conflicts": 0,
    "noops": 0,
    "retries": {
        "bulk": 0,
        "search": 0
    },
    "throttled_millis": 0,
    "requests_per_second": -1,
    "throttled_until_millis": 0,
    "failures": []
}

поэтому, хотя он обновил только 5 документов (я дважды проверил), в окончательном ответе написано «обновлено»: 10. Я ожидал «обновлено»: 5, я что-то упустил? он что-то еще обновляет? Я вижу, что "_version" обновляется для всех документов, то есть даже для документов, у которых нет совпадающей строки.
Заранее спасибо!

ОБНОВЛЕНИЕ:

Большое спасибо, Майк, за быстрый ответ :)
По словам Майка, проверка поля в запросе на обновление должна быть обновлена ​​следующим образом.

"query": {
  "exists": {
    "field": "address"
  }
}

Однако есть еще 1 проблема.
Изначально я свел поля к минимуму для простоты вопроса. На самом деле в полезной нагрузке много полей, и я хочу обновить 3 из них на основе некоторого условия.

Итак, полезная нагрузка выглядит следующим образом

{
    "id":12,
    "address":"temp address",
    "email":"temp email",
    "phone":"temp phone",
    .
    .
    .
}

И я использую следующий скрипт для обновления всех трех полей.

{
  "script": {
     "inline": "if(ctx._source.containsKey(\"address\") && ctx._source.address == "temp address"){ctx._source.address='perm address'}if(ctx._source.containsKey(\"email\") && ctx._source.email == "temp email"){ctx._source.email='perm email'}if(ctx._source.containsKey(\"phone\") && ctx._source.phone == "temp phone"){ctx._source.phone='perm phone'}"
  }
}

мы можем обновить решение Майка для нескольких полей ?? или есть ли альтернативный способ сделать это? Спасибо еще раз !


person SSG    schedule 10.10.2017    source источник


Ответы (1)


Это происходит потому, что даже если вы фактически не изменяете все документы, которые вы извлекаете в запросе _update_by_query, они, по крайней мере, учитываются в вашем запросе как попадания.

Вместо того, чтобы выполнять проверку поля в запросе на обновление, добавьте этот существующий запрос в свой запрос на обновление:

"query": {
  "exists": {
    "field": "address"
  }
}

Редактирование, чтобы ответить на обновленный вопрос: если вы хотите обновить 3 поля, вам, скорее всего, будет проще всего сделать 3 одновременных изменения с помощью одного скрипта. Как показано выше, счетчик на самом деле не отражает фактических изменений, внесенных в документы. Если подсчет абсолютно необходим, вы можете сделать это (и он будет фильтровать любой документ, в котором есть любой из этих 3.)

"query": {
  "bool": {
    "minimum_should_match": 1,
    "should": [
      {
        "term": {
          "address": {
            "value": "temp address"
          }
        }
      },
      {
        "term": {
          "email": {
            "value": "temp email"
          }
        }
      },
      {
      "term": {
        "phone": {
          "value": "temp phone"
        }
      }
    }
  ]
  }
  }
person Miek    schedule 10.10.2017
comment
Привет, Майк, спасибо за очень быстрый ответ :), я обновил вопрос сейчас, не могли бы вы взглянуть на раздел «Обновление». ?? - person SSG; 10.10.2017
comment
Спасибо Майк! Но я считаю, что встроенный скрипт будет выполняться тогда и только тогда, когда все 3 условия совпадают, могут быть случаи, когда только 1 или 2 или все 3 условия совпадают. - person SSG; 11.10.2017
comment
@SSG Он должен соответствовать любому из них. Я обернул термин запросы в контейнер должен вверху. Поскольку Minimum_should_match равен 1 (это значение по умолчанию, я настроил его для демонстрации), любой документ, который соответствует любому из этих утверждений, будет частью результирующего набора. Затем эти результаты будут доступны для вашего сценария обновления. - person Miek; 11.10.2017