Наконец-то я нашел способ обновить свойство name только для определенных вложенных объектов в зависимости от их идентификатора следующим образом:
var result = elasticClient.UpdateByQuery<ProductType>(u => u
.Query(q => q
.Nested(n => n
.Path(Infer.Field<ProductType>(ff => ff.ProductAttributes))
.Query(nq => nq
.Term(Infer.Field<ProductType>(ff => ff.ProductAttributes.First().Id), productAttributeId)
)
)
)
.Script(ss => ss.Inline("if (ctx._source.productAttributes != null){for (item in ctx._source.productAttributes){if (item.id == params.id) {item.name = params.name;}}}")
.Params(new Dictionary<string, object>()
{
{"id", productAttributeId},
{"name", productAttributeName}
}).Lang("painless")
)
.Conflicts(Conflicts.Proceed)
.Refresh(true)
);
А вот сгенерированный запрос:
POST product/producttype/_update_by_query?conflicts=proceed&refresh=true
{
"query": {
"bool": {
"must": [
{
"nested": {
"query": {
"term": {
"productAttributes.id": {
"value": "563243f0-8fbb-4adf-a78d-1339e5971a43"
}
}
},
"path": "productAttributes"
}
}
]
}
},
"script": {
"params": {
"id":"563243f0-8fbb-4adf-a78d-1339e5971a43",
"name": "CPU"
},
"lang": "painless",
"inline": "if (ctx._source.productAttributes != null){for (item in ctx._source.productAttributes){if (item.id == params.id) {item.name = params.name;}}}"
}
}
Так чтовыполняет ли приведенный выше запрос:
Сначала выполняется поиск продуктов, имеющих атрибут productAttribute с идентификатором 563243f0-8fbb-4adf-a78d-1339e5971a43 , а затем он перебирает вложенные объекты productAttributes для обновления только атрибутов сэтот идентификатор, а затем снова индексирует документ.
Я надеюсь, что мой ответ поможет другим, столкнувшимся с проблемами при обновлении вложенных объектов в Elasticsearch.