nested 타입을 _update_by_query를 사용하여 add, update, remove하는 방법
우선 인덱스를 생성한다. (post 인덱스에 comment가 nested로 포함되어 있음)
인덱스 생성
PUT posts
{
"mappings": {
"properties": {
"postId": {
"type": "keyword"
},
"title": {
"type": "keyword"
},
"comments": {
"type": "nested",
"properties": {
"commentId": {
"type": "keyword"
},
"text": {
"type": "text"
}
}
}
}
}
}
데이터 입력
post1 데이터를 입력하자.
POST posts/_doc/1
{
"postId": "post1",
"title": "post 1입니다",
"comments": [
{
"commentId": "post1-comment1",
"text": "post1의 comment1입니다."
}
]
}
[docs] count: 2, deleted: 0
post: 1건, comment: 1건이 추가
comment 추가
post1에 2건의 comment를 추가하자. (comment2, comment3)
POST posts/_update_by_query
{
"script": {
"source": "ctx._source.comments.addAll(params.comments)",
"params": {
"comments": [
{
"commentId": "comment2",
"text": "post1의 comment2입니다."
},
{
"commentId": "comment3",
"text": "post1의 comment3입니다."
}
]
}
},
"query": {
"term": {
"postId": "post1"
}
}
}
[docs] count: 4, deleted: 2 (0 + 2)
기존에 있던 2건(post1, comment1)이 삭제되고 4건(post1, comment1, comment2, comment3)이 추가된다.
comment 수정
comment1의 text를 수정하자.
POST posts/_update_by_query
{
"script": {
"source": """
for (int i=0; i<ctx._source.comments.size(); i++) {
HashMap commentMap = ctx._source.comments.get(i);
if (commentMap.commentId == params.commentId) {
ctx._source.comments[i] = params;
}
}
""",
"params": {
"commentId": "comment1",
"message": "post1의 comment1입니다.(수정)"
}
},
"query": {
"term": {
"postId": "post1"
}
}
}
[docs] count: 4, deleted: 6 (2 + 4)
기존에 있던 4건(post1, comment1, comment2, comment3)이 삭제되고 4건(post1, comment1, comment2, comment3)이 추가된다.
comment 삭제
POST posts/_update_by_query
{
"script": {
"source": "ctx._source.comments.removeIf(comment->params.commentId == comment.commentId)",
"params": {
"commentId": "comment1"
}
},
"query": {
"term": {
"postId": "post1"
}
}
}
[docs] count: 3, deleted: 10 (6 + 4)
기존에 있던 4건(post1, comment1, comment2, comment3)이 삭제되고 3건(post1, comment2, comment3)이 추가된다.
반응형