nested object`로 구성되어 있는 index는 nested 유형에 대해 새로운 document를 생성한다.
예를 들어 nested object를 가지고 있는 문서(부서)에 하나의 값(직원)을 추가하면 1개의 document가 생성될 것 같지만 실제로는 2개의 document가 생성이 된다.
예제를 통해 확인해보자.
[문서 구조]
department (document)
- employees (nested)
부서(department) 인덱스 생성
PUT department
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"employees": {
"type": "nested"
}
}
}
}
mapping 정보 확인
GET department/_mapping
아래와 같이 nested로 생성이 되었다.
{
"department" : {
"mappings" : {
"properties" : {
"employees" : {
"type" : "nested"
},
"name" : {
"type" : "text"
}
}
}
}
}
document 생성
POST /department/_doc/1
{
"name":"개발팀",
"employees": [
{
"firstname": "홍",
"lastname": "길동"
}
]
}
홍길동이 팀원으로 있는 개발팀을 하나 추가하였다.
document 조회
GET department/_doc/1
{
"_index" : "department",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "개발팀",
"employees" : [
{
"firstname" : "홍",
"lastname" : "길동"
}
]
}
}
실제 몇 개의 document가 생성되었는지 _stats
를 통해 확인해보자.
GET department/_stats/docs
결과화면
{
...,
"_all" : {
...
"total" : {
"docs" : {
"count" : 2,
"deleted" : 0
}
}
}
}
위와 같이 1개가 아닌 2개의 document가 생성이 되었다. (document + nested object document)
nested object 추가
그럼 직원을 한명 더 추가해보자.
document의 nested object 추가
employee값만 추가할 것이라 ctx._source를 통해 추가하자.
POST /department/_update/1
{
"script": {
"source": "ctx._source.employees.add(params)",
"params": {
"firstname": "승엽",
"lastname": "이"
}
}
}
추가된 내용을 조회하면
GET department/_doc/1
결과 내용
{
"_index" : "department",
"_type" : "_doc",
"_id" : "1",
"_version" : 2,
"_seq_no" : 1,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "개발팀",
"employees" : [
{
"firstname" : "홍",
"lastname" : "길동"
},
{
"firstname" : "승엽",
"lastname" : "이"
}
]
}
}
기존의 "홍길동"에 이어 "이승엽"이 추가된 것을 확인할 수 있다.
그럼 실제 document는 몇개가 되는지 확인해보자.
GET department/_stats/docs
결과
{
...
"_all" :
...
"total" : {
"docs" : {
"count" : 3,
"deleted" : 2
}
}
}
2개가 삭제가 되었고 현재 총 3개가 있다.
삭제된 2개는 이전에 있었던 문서(개발팀-홍길동)이며 nested object에 1개를 추가하더라도 기존 문서는 모두 삭제되고 새로 3건이 추가된다.
nested object 수정
그럼 nested object의 값을 변경(update)하는 경우에는 document의 수가 어떻게 바뀌는지 확인해보자.
document의 nested object 수정
POST /department/_update/1
{
"script": {
"source": """
ctx._source.employees[0].firstname = params.firstname;
""",
"params": {
"firstname": "김"
}
}
}
document 조회를 해보면 firstname이 "홍"에서 "김"으로 변경되었음을 확인할 수 있다.
GET department/_doc/1
{
"_index" : "department",
"_type" : "_doc",
"_id" : "1",
"_version" : 3,
"_seq_no" : 2,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "개발팀",
"employees" : [
{
"firstname" : "김",
"lastname" : "길동"
},
{
"firstname" : "승엽",
"lastname" : "이"
}
]
}
}
그럼 document의 갯수는 어떻게 변경이 될까?
GET department/_stats/docs
{
...
"_all" : {
...
"total" : {
"docs" : {
"count" : 3,
"deleted" : 5
}
}
}
document 3건에 삭제 5건이다. (이전 ==> count: 3, deleted: 2)
nested object의 값이 변경되더라도 parent, nested 모두 삭제가 되고 새로 insert되는 구조를 가지고 있다.
- 이전) count: 3, deleted: 2
- 변경) count: 5, deleted: 5
이는 루씬(lucene)의 세그먼트 불변성(Immutability)으로 인해 기존 segment는 수정하지 않고 delete 처리 후 insert하는 구조를 가지고 있기 때문이다.