How to delete and add item in nested property in ElasticSearch? most of the examples not working.
2 Answers
I've spent a lot of hours on figuring out how to add new object into nested array in ElasticSearch and how to delete it. There are a llot of answers on StackOverflow but most of them are outdated. So there are examples:
$this->getClient()->update(
[
'index' => $this->getIndexName(),
'id' => $Item->getReportId(),
'body' => [
'script' => [
'lang' => 'painless',
'inline' => 'int idx = -1;
for (int i = 0; i < ctx._source.reports.length; ++i) {
if (ctx._source.reports[i].entry_id == params.entry_id && ctx._source.reports[i].source == params.source) {
idx=i;
}
}
if (idx != -1)
ctx._source.reports.remove(idx);',
'params' => ['entry_id' => (string)$Item->getEntryId(), 'source' => $Item->getTableName()],
],
],
]
);
$this->getClient()->update(
[
'index' => $this->getIndexName(),
'id' => $Item->getReportId(),
'body' => [
'script' => [
'lang' => 'painless',
'inline' => 'ctx._source.reports.add(params.object)',
'params' => ['object' => $entry]
],
],
]
);
1 Comment
Saturn
(string) conversion here due to == cares about typesA simpler way of removing items (inspired from my other answer here).
No for loops, no ifs :-)
$this->getClient()->update(
[
'index' => $this->getIndexName(),
'id' => $Item->getReportId(),
'body' => [
'script' => [
'lang' => 'painless',
'inline' => 'ctx._source.reports.removeAll{ it -> it.entry_id == params.entry_id && it.source == params.source }',
'params' => ['entry_id' => (string)$Item->getEntryId(), 'source' => $Item->getTableName()],
],
],
]
);