Elastic Search

Ch03. 데이터 모델링 - Document API 이해하기

webmaster 2025. 9. 13. 22:41
728x90

문서 파라미터

DocumentAPI에서는 다양한 파라미터를 제공한다.

 

문서 ID 자동 생성

POST movie_dynamic/_doc
{
  "movieId": "20173732",
  "movieNm": "살아남은 아이",
  "movieNmEn": "Last Child",
  "typeNm": "장편"
}
  • 문서를 생성할 때는 기본적으로 ID가 필요하며, 각 문서는 ID로 구분한다. (만약 문서 생성 시, 지정하지 않으면 자동 ID를 부여하며 UUID 형태이다.)
  • 문서 생성 시, 자동으로 UUID를 생성해 준다.

버전 관리

PUT movie_dynamic/_doc/1
{
  "nationAlt": "한국"
}
  • 색인된 모든 문서는 버전 값을 가지고 있으며, 색인할 때 결과에 포함되어 나타난다.
  • 최초 1을 갖게 되고 문서에 변경이 일어날 때마다 버전 값이 증가한다.
  • UpdataAPI 호출 시 내부적으로 스냅숏을 생성해서 문서를 수정, 재색인하게 되는데 이때 버전 정보를 비교해 값이 달라졌으면 실패로 처리한다.

오퍼레이션 타입

PUT movie_dynamic/_doc/1?op_type=create
{
  "movieId": "20173732",
  "movieNm": "살아남은 아이",
  "movieNmEn": "Last Child",
  "typeNm": "단편"
}
  • 일반적으로는 ID가 존재할 경우 update 작업이, ID가 없을 경우 Create 작업이 일어나게 되는데, 이때 존재할 경우 Update가 아닌 색인이 실패하기를 원한다면, op_type을 이용하면 된다.
  • index API를 호출할 때, op_type 파라미터를 이용해 수행되는 작업의 유형을 강제 지정할 수 있다.
  • 해당 예시로 2번째 요청 시 이미 존재한다는 오류가 발생하면서 색인에 실패

타임아웃 설정

PUT movie_dynamic/_doc/1?timeout=5m
{
  "movieId": "20173732",
  "movieNm": "살아남은 아이",
  "movieNmEn": "Last Child",
  "typeNm": "장편"
}
  • 일반적으로 색인을 요청할 때 대부분 즉시 처리되지만, 이미 색인 작업이 진행 중일 경우에는 일정 기간 대기를 하는데 기본적으로 1분 대기 후 지날 경우 요청이 실패하게 된다.
  • timeout 파라미터를 설정해서 대기 시간을 조절할 수 있다.

인덱스 매핑 정보 자동 생성

action.auto_create_index //인덱스를 자동 생성할지 여부를 결정합니다.
index.mapper. dynamic // 동적 매핑(Dynamic Mapping)을 사용할지 여부를 설정합니다.
  • IndexAPI로 문서를 색인 시 기존 정의되지 않은 필드의 정보가 존재할 경우 어떻게 할지 결정해야 한다(디폴트는 동적 매핑 허용)
  • 상황에 따라서는 기능을 비활성화해야 할 때가  있다.
  • elasticsearch.yml 에서 설정하면 된다.

Index API

문서를 특정 인덱스에 추가하는 데 사용되며, 새로 추가된 문서는 버전 값이 1로, 업데이트마다 버전이 증가한다.

PUT movie_dynamic/_doc/1
{
  "movieId": "20173732",
  "movieNm": "살아남은 아이",
  "movieNmEn": "Last Child",
  "typeNm": "장편"
}

결과

{
  "_index": "movie_dynamic",
  "_type": "_doc",
  "_id": "1",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 0,
  "_primary_term": 1
}
  • _shards 항목은 몇 개의 샤드에서 명령이 수행됐는지에 대한 정보를 나타낸다.
    • total: 복제돼야 하는 전체 샤드 개수
    • successful: 성공적으로 복제된 샤드 개수
    • failed: 복제에 실패한 샤드 개수
    • indexAPI는 최소 한 개 이상의 successful 항목이 있어야 성공한 것으로 본다.

Get API

특정 문서를 인덱스에서 조회할 때 사용하는 API이다. 조회하고자 하는 문서의 ID를 명시적으로 지정해서 사용한다.

일반적으로 조회되는 문서의 내용은 _source 항목으로 확인할 수 있다.

GET movie_dynamic/_doc/1

//GET movie_dynamic/_doc/1?_source_exclude=movieNm //제외할 Source 항목 입력

결과

{
  "_index": "movie_dynamic",
  "_type": "_doc",
  "_id": "1",
  "_version": 1,
  "found": true,
  "_source": {
    "movieId": "20173732",
    "movieNm": "살아남은 아이",
    "movieNmEn": "Last Child"
  }
}
  • 일반적인 상황에서는 모든 필드가 _source 필드의 일부분으로 저장된다. -> 필드가 매우 방대할 경우 문제가 될 수 있다.
  • 특정 필드를 _source 항목으로 제공하지 않도록 설정하기 위해서는 _source_exclude 옵션을 이용해 제외할 필드명을 지정할 수 있다.

DeleteAPI

DeleteAPI를 이용하면, 문서를 삭제할 수 있으며, result 항목에 "delete" 값이 반환되며 version 값이 1만큼 증가한다.

DELETE movie_dynamic/_doc/1
//DELETE movie_dynamic //인덱스 전체 삭제

 

결과

{
  "_index": "movie_dynamic",
  "_type": "_doc",
  "_id": "1",
  "_version": 2,
  "result": "deleted",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 1,
  "primary_term": 1
}
  • 특정 문서가 아닌 인덱스 전체를 삭제하고 싶다면, 인덱스 명을 입력하면 된다.
    • 인덱스 삭제 시 모든 문서가 삭제되고 복구할 수 없다.

Delete By Query API

특정 인덱스에서 검색을 수행한 후, 그 결과에 해당하는 문서만 삭제하고 싶은 경우 Delete By Query API를 사용

POST movie_dynamic/_delete_by_query
{
  "query": {
    "term": {
      "movieCd": "20173732"
    }
  }
}

 

결과

{
  "took": 17,
  "timed_out": false,
  "total": 1,
  "deleted": 1,
  "batches": 1,
  "version_conflicts": 0,
  "noops": 0,
  "retries": {
    "bulk": 0,
    "search": 0,
    "throttled_millis": 0,
    "requests_per_second": -1.0,
    "throttled_until_millis": 0
  },
  "failures": []
}
  • Delete By Query API를 호출 시, 해당 인덱스의 스냅숏을 불러와 스냅숏이 있는 문서의 버전을 기반으로 삭제를 수행한다.
  • 만약 대량의 수정 작업이 진행 중일 때, 삭제 수행 시 버전이 일치하지 않게 되어서 version_conflicts 항목을 통해 삭제에 실패한 문서의 건수를 출력한다.

Update API

UpdateAPI를 이용해서 스크립트를 바탕으로 문서를 수정할 수 있다.(ctx._source. 필드명과 같은 형태로 접근)

POST movie_dynamic/_doc/1/_update
{
  "script": {
    "source": "ctx._source.counter += params.count",
    "lang": "painless",
    "params": {
      "count": 1
    }
  }
}
  • 엘라스틱서치의 업데이트는 실제 업데이트가 아니며, Update API가 호출되면 엘라스틱 서치가 index에서 문서를 가져와 스크립트를 수행한 후, 이를 재색인한다.
    • UpdateAPI를 호출하기 위해서는 _source 필드가 활성화되어 있어야 한다.
  • _source 변수뿐 아니라 _index, _type, _id, _version, _routing, _now 등 추가 변수도 사용할 수 있다.

Bulk API

BulkAPI를 이용하면, 한 번의 API 호출로 다수의 문서를 색인하거나 삭제할 수 있다. 특히 색인 작업의 경우 한 번에 처리함으로써 색인 속도를 크게 향상할 수 있어 대량 색인에는 Bulk API를 사용하는 것이 좋다.

POST _bulk
{ "index": { "_index": "movie_dynamic", "_id": "1" } }
{ "title": "살아남은 아이" }
{ "delete": { "_index": "movie_dynamic", "_id": "2" } }
{ "index": { "_index": "movie_dynamic", "_id": "3" } }
{ "title": "프렌즈: 몬스터섬의 비밀" }
{ "update": { "_index": "movie_dynamic", "_id": "1" } }
{ "doc": { "movieNmEn": "Last Child" } }
  • 인덱스를 생성하면서, id가 1, 3인 문서를 추가, ID가 2인 문서를 삭제, ID가 1인 문서의 속성을 수정한다.
  • Bulk API는 단점으로는 여러 건의 데이터가 한 번에 처리되는 것이 아니기 때문에 도중에 실패가 발생하더라도 이미 갱신되거나 수정된 결과는 롤백되지 않는다.
    • 항상 처리 결과를 확인해야 한다.

Reindex API

한 인덱스에서 다른 인덱스로 문서를 복사할 때 자주 사용한다

POST /_reindex
{
  "source": {
    "index": "movie_dynamic"
  },
  "dest": {
    "index": "movie_dynamic_new"
  }
}
  • source가 복사할 인덱스를 나타내고 dest가 복사될 인덱스를 나타낸다.
POST _reindex
{
  "source": {
    "index": "movie_dynamic",
    "query": {
      "term": {
        "title.keyword": "프렌즈: 몬스터섬의 비밀"
      }
    }
  },
  "dest": {
    "index": "movie_dynamic_new"
  }
}
  • 특정 조회 결과와 일치하는 문서만 복사하고 싶을 경우 source 항목에 쿼리를 포함시켜서 쿼리 결과에 일지 하는 문서만 복사할 수 있다
POST _reindex
{
  "size": 10000,
  "source": {
    "index": "movie_dynamic",
    "sort": [
      { "counter": "desc" }
    ]
  },
  "dest": {
    "index": "movie_dynamic_new"
  }
}
  • 특정 문서를 복사해서 새로운 인덱스를 만들 때 정렬 방식으로 데이터를 정렬한 후 복사하는 것도 가능하다.
  • 기본적으로 reindexAPI는 1000건 단위로 스크롤을 수행하며, size 항목을 지정해 스크롤 크기를 변경할 수 있다.
728x90