Как объединить объект вместо того, чтобы полностью заменить его с помощью API обновления (безболезненно) при записи ElasticSearch
Сценарий: есть документ A в ElasticSearch, и я хочу объединить в этот документ некоторые поля, существующие в документе B.
Документ А:
{
"id": 121423,
"name": "Sample Name",
"timestamp": "2020-10-01T00:12:00",
"age": 24
}
Документ B:
{
"city": "New York",
"job": "programmer"
}
Чтобы написать в этом документе, я могу использовать путь записи ES и подобное тело:
{"update":{"_index":"test-index","_id":"121423"}}
{"script": {"source":"if( ctx._source.containsKey('id') ){ ctx._source = params.param1; }","lang":"painless","params":{"param1":{"city": "New York", "job": "programmer"}}},"upsert":{"id":121423,"name": "Sample Name","timestamp": "2020-10-01T00:12:00","age": 24}}
Но, если документ A существует на ES, например, check do (if( ctx._source.containsKey('id') )
) документ полностью перезаписывается. Я могу заменить приписанные параметры, чтобы выбрать каждый элемент поэтапно, например:
{ ctx._source.city = params.param1.city; ctx._source.job = params.param1.job }
Это решит мою проблему, НО из-за этого у меня возникнет проблема, логика не может быть статичной, потому что в реальном мире документ имеет много (очень много) полей, и поддержка приложения будет сложной. Желаемый документ в последнем обновлении должен быть примерно таким:
{
"id": 121423,
"name": "Sample Name",
"timestamp": "2020-10-01T00:12:00",
"age": 24,
"city": "New York",
"job": "programmer"
}
Итак, вопрос в том, как я могу обновить документ, добавляя новые поля небольшими шагами или используя только один оператор?
1 ответ
Вам, вероятно, следует просто добавить "doc_as_upsert": true Я никогда не пробовал это со сценарием, но он должен работать.
{ "update" : {"_id" : "2", "_index" : "index1", "retry_on_conflict" : 3} }
{ "doc" : {"field" : "value"}, "doc_as_upsert" : true }