Spec-Zone.ru › Elasticsearch 7
›Elasticsearch Guide [7.17] ›REST API ›Документальные API

API обновления

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

Запрос

POST /<index>/_update/<_id>

Предварительные условия

  • Если включены функции безопасности Elasticsearch, у вас должны быть index или write права на индекс для целевого индекса или алиаса индекса.

Описание

Позволяет вам выполнить скриптовое обновление документов. Скрипт может обновлять, удалять или пропускать изменение документа. API обновления также поддерживает передачу частичного документа, который объединяется с существующим документом. Чтобы полностью заменить существующий документ, используйте index API.

Данная операция:

  1. Получает документ (совмещённый с фрагментом) из индекса.
  2. Выполняет указанный скрипт.
  3. Индексирует результат.

Документ по-прежнему должен быть повторно индексирован, но использование update уменьшает количество сетевых запросов и снижает вероятность конфликтов версий между операциями GET и индексирования.

Поле _source должно быть включено для использования update. В дополнение к _source, вы можете получить доступ к следующим переменным через карту ctx: _index, _type, _id, _version, _routing и _now (текущая метка времени).

Параметры пути

<index>
(Обязательно, строка) Название целевого индекса. По умолчанию индекс создаётся автоматически, если он не существует. Дополнительная информация приведена в разделе Автоматическое создание потоков данных и индексов.
<_id>
(Обязательно, строка) Уникальный идентификатор документа, подлежащего обновлению.

Параметры запроса

if_seq_no
(Необязательно, целое число) Выполнить операцию только в том случае, если у документа есть этот номер последовательности. См. Оптимистический контроль конкуретности.
if_primary_term
(Необязательно, целое число) Выполнить операцию только в том случае, если у документа есть этот первичный термин. См. Оптимистический контроль конкуретности.
lang
(Необязательно, строка) Язык скрипта. По умолчанию: painless.
require_alias
(Необязательно, логическое значение) Если true, целевой объект должен быть алиасом индекса. По умолчанию false.
refresh
(Необязательно, перечисление) Если true, Elasticsearch обновляет затронутые фрагменты, чтобы эта операция была видна в результатах поиска. Если wait_for, ожидается обновление для отображения. Если false, никаких обновлений не происходит. Допустимые значения: true, false, wait_for. По умолчанию: false.
retry_on_conflict
(Необязательно, целое число) Указывает количество попыток повтора операции при возникновении конфликта. По умолчанию 0.
routing
(Необязательно, строка) Пользовательское значение, используемое для маршрутизации операций к определённому фрагменту.
_source
(Необязательно, список) Установите в true для включения получения исходных данных (по умолчанию: false). Также можно указать список полей, которые нужно получить, разделённые запятыми.
_source_excludes
(Необязательно, список) Укажите поля исходных данных, которые нужно исключить.
_source_includes
(Необязательно, список) Укажите поля исходных данных, которые нужно получить.
timeout

(Необязательно, единицы времени) Период ожидания следующих операций:

  • Обновления динамического отображения
  • Ожидание активных фрагментов

По умолчанию 1m (одна минута). Это гарантирует, что Elasticsearch будет ожидать по крайней мере указанного времени перед ошибкой. Фактическое время ожидания может быть больше, особенно при нескольких ожиданиях.

wait_for_active_shards

(Необязательно, строка) Количество активных копий фрагментов, необходимое для продолжения операции. Установите значение all или любое положительное целое число до общего количества фрагментов в индексе (number_of_replicas+1). По умолчанию 1, первичный фрагмент.

См. Активные фрагменты.

Примеры

Сначала давайте индексируем простой документ:

PUT test/_doc/1
{
  "counter" : 1,
  "tags" : ["red"]
}

Чтобы увеличить счётчик, можно отправить запрос на обновление со следующим скриптом:

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

Аналогично, вы можете использовать и обновлять скрипт для добавления тега в список тегов (это просто список, поэтому тег добавляется, даже если он уже существует):

POST test/_update/1
{
  "script": {
    "source": "ctx._source.tags.add(params.tag)",
    "lang": "painless",
    "params": {
      "tag": "blue"
    }
  }
}

Вы также можете удалить тег из списка тегов. Функция Painless для remove тега принимает индекс массива элемента, который вы хотите удалить. Для предотвращения возможной ошибки во время выполнения, сначала необходимо убедиться, что тег существует. Если список содержит дубликаты тега, этот скрипт удаляет только одно вхождение.

POST test/_update/1
{
  "script": {
    "source": "if (ctx._source.tags.contains(params.tag)) { ctx._source.tags.remove(ctx._source.tags.indexOf(params.tag)) }",
    "lang": "painless",
    "params": {
      "tag": "blue"
    }
  }
}

Вы также можете добавлять и удалять поля из документа. Например, этот скрипт добавляет поле new_field:

POST test/_update/1
{
  "script" : "ctx._source.new_field = 'value_of_new_field'"
}

Напротив, этот скрипт удаляет поле new_field:

POST test/_update/1
{
  "script" : "ctx._source.remove('new_field')"
}

Следующий скрипт удаляет подполе из поля объекта:

POST test/_update/1
{
  "script": "ctx._source['my-object'].remove('my-subfield')"
}

Вместо обновления документа, вы также можете изменить выполняемую операцию внутри скрипта. Например, этот запрос удаляет документ, если поле tags содержит green, иначе ничего не делает (noop):

POST test/_update/1
{
  "script": {
    "source": "if (ctx._source.tags.contains(params.tag)) { ctx.op = 'delete' } else { ctx.op = 'none' }",
    "lang": "painless",
    "params": {
      "tag": "green"
    }
  }
}
Обновить часть документа

Следующее частичное обновление добавляет новое поле в существующий документ:

POST test/_update/1
{
  "doc": {
    "name": "new_name"
  }
}

Если оба doc и script указаны, то doc игнорируется. Если вы указываете скриптовое обновление, включите поля, которые нужно обновить, в скрипт.

Обнаружение операций без изменений

По умолчанию обновления, которые ничего не изменяют, обнаруживают это и возвращают "result": "noop":

POST test/_update/1
{
  "doc": {
    "name": "new_name"
  }
}

Если значение name уже new_name, запрос на обновление игнорируется, и элемент result в ответе возвращает noop:

{
   "_shards": {
        "total": 0,
        "successful": 0,
        "failed": 0
   },
   "_index": "test",
   "_type": "_doc",
   "_id": "1",
   "_version": 2,
   "_primary_term": 1,
   "_seq_no": 1,
   "result": "noop"
}

Вы можете отключить это поведение, установив "detect_noop": false:

POST test/_update/1
{
  "doc": {
    "name": "new_name"
  },
  "detect_noop": false
}
Upsert

Если документ ещё не существует, содержимое элемента upsert вставляется как новый документ. Если документ существует, выполняется script:

POST test/_update/1
{
  "script": {
    "source": "ctx._source.counter += params.count",
    "lang": "painless",
    "params": {
      "count": 4
    }
  },
  "upsert": {
    "counter": 1
  }
}
Скриптовый upsert

Чтобы запустить скрипт независимо от наличия документа, установите scripted_upsert в true:

POST test/_update/1
{
  "scripted_upsert": true,
  "script": {
    "source": """
      if ( ctx.op == 'create' ) {
        ctx._source.counter = params.count
      } else {
        ctx._source.counter += params.count
      }
    """,
    "params": {
      "count": 4
    }
  },
  "upsert": {}
}
Документ как upsert

Вместо отправки частичного doc плюс документа upsert, вы можете установить doc_as_upsert в true, чтобы использовать содержимое doc в качестве значения upsert:

POST test/_update/1
{
  "doc": {
    "name": "new_name"
  },
  "doc_as_upsert": true
}

Использование конвейеров обработки с doc_as_upsert не поддерживается.

© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-update.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API