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

Рассмотрим следующий документ

{
 "title": "My first blog entry",
 "text": "Starting to get the hang of this...",
 "tags": [ "testing" ], 
 "views": 0 
}

Мне нужно запустить операцию upsert. Если я сталкиваюсь с данными типа

{
 "id": 1,
 "tags": [ "new tag" ]
}

Я хочу обновить существующий документ с тем же идентификатором. Поэтому результат должен быть:

{
 "id": 1,
 "title": "My first blog entry",
 "text": "Starting to get the hang of this...",
 "tags": [ "testing", "new tag" ], 
 "views": 0 
}

Если документ с таким же идентификатором не существует, я хочу создать новый.

Теперь в таких базах данных, как mongoDB, я мог бы использовать обновление с помощью $addToSet или $push. Я не мог найти подобную операцию в Elasticsearch.

Я читал, что это можно сделать, написав скрипты в groovy. Однако это нужно сделать в файле, содержащем 200 миллионов записей. Я не уверен, могу ли я использовать groovy в сочетании с массивным API. Возможно ли это?

1 ответ

Для этого вам не нужно использовать массовый API. Вы можете использовать запрос upsert. Запрос на повышение может также быть встроен в массовый запрос.

curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
 "script": "if (ctx._source.tags.contains(\"tags\")) {ctx._source.tags += tag;} else {ctx._source.tags = [tag]}",
 "params": {
 "tag": "newTag"
 },
 "upsert": {
 "title": "My first blog entry",
 "text": "Starting to get the hang of this...",
 "tags": [
 "newTag"
 ],
 "views": 0
 }
}'

licensed under cc by-sa 3.0 with attribution.