从数组弹性search中删除对象
我需要从满足条件的数组中删除对象,我可以根据条件更新数组的对象,如下所示:
PUT twitter/twit/1 {"list": [ { "tweet_id": "1", "a": "b" }, { "tweet_id": "123", "a": "f" } ] } POST /twitter/twit/1/_update {"script":"foreach (item :ctx._source.list) { if item['tweet_id'] == tweet_id) { item['new_field'] = 'ghi'; } }", "params": {tweet_id": 123"} }
这是工作
删除我正在做这个
POST /twitter/twit/1/_update { "script": "foreach (item : ctx._source.list) { if item['tweet_id'] == tweet_id) { ctx._source.list.remove(item); } }", "params": { tweet_id": "123" } }
但是这不起作用,并给出这个错误,
ElasticsearchIllegalArgumentException [未能执行脚本]; 嵌套:ConcurrentModificationException; 错误:ElasticsearchIllegalArgumentException [未能执行脚本]; 嵌套:ConcurrentModificationException
我能够删除整个arrays或整个领域使用
"script": "ctx._source.remove('list')"
我也能够通过指定一个对象的所有键使用从数组中删除对象
"script":"ctx._source.list.remove(tag)", "params" : { "tag" : {"tweet_id": "123","a": "f"}
我的节点模块弹性search版本是2.4.2,弹性search服务器是1.3.2
你得到的是因为你试图修改一个列表,同时遍历它,这意味着你想改变一个列表的对象,同时列出这些对象。
你反而需要这样做:
POST /twitter/twit/1/_update { "script": "item_to_remove = nil; foreach (item : ctx._source.list) { if (item['tweet_id'] == tweet_id) { item_to_remove=item; } } if (item_to_remove != nil) ctx._source.list.remove(item_to_remove);", "params": {"tweet_id": "123"} }
如果您有多个符合条件的项目,请改用列表:
POST /twitter/twit/1/_update { "script": "items_to_remove = []; foreach (item : ctx._source.list) { if (item['tweet_id'] == tweet_id) { items_to_remove.add(item); } } foreach (item : items_to_remove) {ctx._source.list.remove(item);}", "params": {"tweet_id": "123"} }
对于那些在elasticsearch 2.0中需要这个工作的人来说,这个nil
和foreach
不会被groovy所认可。
所以这是一个更新的版本,包括一个选项用一个新对象replace一个具有相同ID的项目。
并通过它的upsert
将确保项目被添加即使文件不存在
{ "script": "item_to_remove = null; ctx._source.delivery.each { elem -> if (elem.id == item_to_add.id) { item_to_remove=elem; } }; if (item_to_remove != null) ctx._source.delivery.remove(item_to_remove); if (item_to_add.size() > 1) ctx._source.delivery += item_to_add;", "params": {"item_to_add": {"id": "5", "title": "New item"}}, "upsert": [{"id": "5", "title": "New item"}] }