В Elasticsearch у меня есть объект, содержащий массив объектов. Каждый объект в массиве имеет поля type
, id
, updateTime
, value
.
Мой входной параметр - это массив, который содержит объекты одного типа, но разные значения и время обновления. Я хотел бы обновить объекты с новым значением, когда они существуют, и создать новые, когда их нет.
Я хотел бы использовать сценарий P безболезненно, чтобы обновить их, но сохранить их различными, так как некоторые из них могут перекрываться . Проблема в том, что мне нужно использовать как type
, так и id
, чтобы сохранить их уникальность. До сих пор я делал это с помощью подхода грубой силы, вложенного for
l oop и сравнения элементов обоих массивов, но я не очень этому рад.
Одна из идей - взять массив из источника создать временную HashMap для быстрого поиска, обработки ввода и последующего сохранения всех объектов обратно в источник.
Могу ли я создать HashMap с настраиваемым объектом (класс с type
и id
) в качестве ключа? Если да, то как это сделать? Я не могу добавить определение класса в сценарий.
Вот отображение. Все поля отключены, поскольку я использую их только в качестве промежуточного состояния и запроса с использованием других полей.
{
"properties": {
"arrayOfObjects": {
"properties": {
"typ": {
"enabled": false
},
"id": {
"enabled": false
},
"value": {
"enabled": false
},
"updated": {
"enabled": false
}
}
}
}
}
Пример do c.
{
"arrayOfObjects": [
{
"typ": "a",
"id": "1",
"updated": "2020-01-02T10:10:10Z",
"value": "yes"
},
{
"typ": "a",
"id": "2",
"updated": "2020-01-02T11:11:11Z",
"value": "no"
},
{
"typ": "b",
"id": "1",
"updated": "2020-01-02T11:11:11Z"
}
]
}
И, наконец, часть скрипта в его нынешнем виде. Скрипт выполняет и другие функции, поэтому я вырезал их для краткости.
if (ctx._source.arrayOfObjects == null) {
ctx._source.arrayOfObjects = new ArrayList();
}
for (obj in params.inputObjects) {
def found = false;
for (existingObj in ctx._source.arrayOfObjects) {
if (obj.typ == existingObj.typ && obj.id == existingObj.id && isAfter(obj.updated, existingObj.updated)) {
existingObj.updated = obj.updated;
existingObj.value = obj.value;
found = true;
break;
}
}
if (!found) {
ctx._source.arrayOfObjects.add([
"typ": obj.typ,
"id": obj.id,
"value": params.inputValue,
"updated": obj.updated
]);
}
}