elasticsearch / / 2022. 12. 31. 14:52

[elasticsearch] nested object 추가,수정 시 docs 수 변화

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하는 구조를 가지고 있기 때문이다.

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유