如何通过Logstash的Elasticsearch脚本合并数组型文档?
Elasticsearch数组元素追加问题解决
问题场景
已有Elasticsearch文档结构:
{ "_source": { "name": "xxx", "recall": [ { "title": "xxx-a", "date": "2020-12-10", "otherB": "abc" } ] } }
新插入的文档结构:
{ "_source": { "name": "xxx", "recall": [ { "title": "xxx-b", "date": "2021-12-10", "otherB": "abcd" } ] } }
期望合并后的结果:
{ "_source": { "name": "xxx", "recall": [ { "title": "xxx-a", "date": "2020-12-10", "otherB": "abc" }, { "title": "xxx-b", "date": "2021-12-10", "otherB": "abcd" } ] } }
现有脚本问题
当前使用的Logstash脚本执行后出现数组嵌套:
script_lang => "painless" script =>"if (ctx._source.containsKey('recall'))ctx._source.recall.addAll(params.event.recall);}"
错误结果:
{ "_source": { "name": "xxx", "recall": [ { "title": "xxx-a", "date": "2020-12-10", "otherB": "abc" }, [ { "title": "xxx-b", "date": "2021-12-10", "otherB": "abcd" } ] ] } }
问题原因:addAll方法直接将params.event.recall数组作为单个元素添加到已有数组中,而非遍历数组元素逐个追加。
修正后的脚本
修改脚本为遍历新数组的每个元素,逐个添加到已有数组中,同时兼容已有文档无recall字段的场景:
script_lang => "painless" script => "if (ctx._source.containsKey('recall')) { for (item in params.event.recall) { ctx._source.recall.add(item); } } else { ctx._source.recall = params.event.recall; }"
验证结果
执行修正后的脚本后,recall数组会正确追加元素,得到期望的合并结构。
内容的提问来源于stack exchange,提问作者Zoey.L
相关产品推荐
相关产品推荐

