5.7.1: 전체 문서 업데이트 방식
Elasticsearch에는 전통적인 의미의 업데이트 연산이 존재하지 않습니다. 대신 새 문서로 기존 문서를 대체하는 방식을 사용합니다. 내부적으로 Elasticsearch는 이전 문서를 삭제 대상으로 표시하고, 완전히 새로운 문서를 추가하여 인덱싱합니다. 이전 버전의 문서는 즉시 사라지지 않지만, 접근할 수 없게 됩니다.
PUT /website/blog/123
{
"title": "My first blog entry2",
"text": "I am starting to get the hang of this...",
"date": "2014/01/02"
}
5.7.2: 부분 업데이트 (Partial Update)
앞서 설명한 전체 문서 업데이트 방식은 문서가 매우 크지만 일부 필드만 변경하고자 할 때 비효율적입니다. 이런 상황에서는 부분 업데이트가 더 적합합니다. 하지만 중요한 점은, 전체 업데이트든 부분 업데이트든 내부 동작 방식은 동일합니다. 즉, 기존 문서를 찾아 삭제 표시하고 새 문서를 추가합니다.
프로세스 단계는 다음과 같습니다:
- 기존 문서에서 JSON 데이터 읽기
- 데이터 수정
- 기존 문서 삭제 표시
- 새 문서 인덱싱
POST /website/blog/123/_update
{
"doc" : {
"tags" : [ "testing" ],
"views": 0
}
}
부분 업데이트에서는 반드시 POST 메서드와 _update 엔드포인트를 사용해야 합니다.
5.7.3: Groovy 스크립트를 이용한 부분 업데이트
API만으로는 복잡한 로직을 처리하기 어려울 때, Elasticsearch는 자체 스크립트 기능을 제공합니다. 이 스크립트는 검색, 정렬, 집계, 문서 업데이트 등 다양한 API에서 활용할 수 있습니다.
기본 스크립트 언어는 Groovy로, JavaScript와 유사한 문법을 가진 빠르고 기능이 풍부한 언어입니다. Groovy는 샌드박스(sandbox) 환경에서 실행되어 악의적인 사용자나 서버 공격을 방지합니다.
스크립트는 update API를 통해 _source 필드 내용을 변경할 수 있으며,
스크립트 내부에서는 ctx._source로 접근합니다.
예를 들어, 블로그 조회 수를 증가시키는 스크립트:
POST /website/blog/123/_update
{
"script" : "ctx._source.views+=1"
}
5.7.4: 존재하지 않는 문서에 대한 업데이트 처리
부분 업데이트 시 대상 문서가 존재하지 않으면 요청이 실패합니다. 하지만 경우에 따라 존재하지 않는 문서에 대해 업데이트(또는 생성)를 시도해야 할 필요가 있습니다.
다음 예제는 존재하지 않는 문서를 업데이트하려 할 때 발생하는 오류입니다:
POST /website/blog/1/_update
{
"script" : "ctx._source.views+=1"
}
# 오류: "type": "document_missing_exception"
이를 해결하기 위해 upsert 키워드를 사용합니다.
upsert는 문서가 없을 경우 새 문서를 생성하는 역할을 합니다.
POST /website/blog/1/_update
{
"script" : "ctx._source.views+=1",
"upsert": {
"views": 2
}
}
부분 업데이트에서 upsert 동작 방식:
- 문서가 존재하지 않을 때:
upsert구문이 실행되어 새 문서 생성 - 문서가 이미 존재할 때:
script구문이 실행되어 기존 문서 업데이트