在更新es数据时,可能会遇到更新nested结构[obj1, obj2, …]数据的问题,第一种方法是找到这个objn,然后直接更新对应元素;第二种方法比较简单粗暴,直接删除这个objn,然后重新插入新的objn.
这里记录一下项目中使用第二种方式的处理过程,其中遇到的难点就是怎么删除这个数组对象中的内容。
翻阅网上资料大多都已过时,基本都是针对lang: groovy语法的处理方案,而ES 6.x 默认使用的是lang: painless.
而painless 提供的remove方法,对[obj1,obj2, …]这种类型不适用。
查看es的painless 语法文档,removeIf方法正好能解决nested array object 的删除问题
list.removeIf(item -> item == 2);
具体使用示例:
// 一个带有nested array object 样式的Document数据结构
{
"threadId": "1",
"subject": "test",
"messages": [
{
"messageId": 1,
"content": "test1"
},
{
"messageId": 2,
"content": "test1"
}
]
}
curl -XPOST <http://localhost:9200/myindex/mytype/_mapping> -H 'Content-Type:application/json' -d'
{
"properties": {
"messages": {
"type": "nested"
}
}
}'
curl -XPOST <http://localhost:9200/myindex/mytype/1> -H 'Content-Type:application/json' -d'
{
"threadId": "1",
"subject": "test",
"messages": [
{
"messageId": 1,
"content": "test1"
},
{
"messageId": 2,
"content": "test1"
}
]
}'
使用第二种方式处理数据 把 { “messageId”: 1, “content”: “test1” } 更新为 { “messageId”: 1, “content”: “new test” }
做法就是先把老的数据删除,然后把新的数据插入进去。
curl -XPOST <http://localhost:9200/myindex/mytype/1/_update> -H 'Content-Type:application/json' -d'
{
"script" : {
"source": "ctx._source.messages.removeIf(item -> item.messageId == 1);ctx._source.messages.add(params.message)",
"lang": "painless",
"params" : {
"message" : {
"messageId": 1,
"content": "new test"
}
}
}
}'
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "myindex",
"_type": "mytype",
"_id": "1",
"_score": 1,
"_source": {
"threadId": "1",
"subject": "test",
"messages": [
{
"messageId": 2,
"content": "test1" },
{
"messageId": 1,
"content": "new test" }
]
}
}
]
}
}