09. 문서관리 API(Document API)
엘라스틱서치에서 제공하는 대표적인 Document API
Index API : 문서를 생성
Get API : 문서를 조회
Delete API : 문서를 삭제
Update API : 문서를 수정
Bulk API : 대량의 문서를 처리
Reindex API : 문서를 복사
1. 문서 파라미터
_id | 문서를 생성할 때 기본적으로 ID가 반드시 필요하다. 문서 추가 시 ID를 지정하지 않으면 엘라스틱서치가 자동으로 ID를 부여한다. (UUID 형태의 값) |
_version | 색인된 모든 문서는 버전 값을 가지고 있다. 기본적으로 버전은 1부터 시작해서 도큐먼트가 갱신/삭제될 때마다 증가한다. 직접 버전 값을 입력할 수 있으나 반드시 정숫값이어야 한다. |
op_type | 일반적으로 ID 존재 시 update, 미존재 시 create 작업이 일어난다. Index API를 호출할 때 op_type 파라미터를 이용하면 수행되는 작업의 유형을 강제로 지정할 수 있다. 예) PUT movie_dynamic/_doc/1?op_type=create { ... } |
timeout | 대기 시간을 조절한다. (기본값 : 1분) 예) PUT movie_dynamic/_doc/1?timeout=5m { ... } |
2. Index API
문서를 특정 인덱스에 추가하는 데 사용됩니다.
# 요청
PUT movie_dynamic/_doc/1
{
"movieCd": "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
}
> Index API는 최소 한 개 이상의 successful 항목이 있어야 성공한 것으로 간주합니다.
3. Get API
특정 문서를 인덱스에서 조회할 때 사용하는 API입니다. 조회하고자 하는 문서의 ID를 명시적으로 지정해서 사용합니다. 일반적으로 조회되는 문서의 내용은 _source 항목으로 확인할 수 있습니다.
# 요청
GET movie_dynamic/_doc/1
# _source_exclude 옵션 : 제외할 필드명 지정
# 예 : GET movie_dynamic/_doc/1?_source_exclude=movieNm
# 결과
{
"_index": "movie_dynamic",
"_type": "_doc",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"movieCd": "20173732",
"movieNm": "살아남은 아이",
"movieNmEn": "Last Child"
}
}
4. Delete API
문서를 삭제하는 API입니다. result 항목에 "deleted" 값이 반환되며 version 값이 1만큼 증가합니다.
DELETE movie_dynamic/_doc/1
특정 문서가 아니라 인덱스 전체를 삭제하고 싶을 때는 인덱스명을 입력하면 됩니다.
DELETE movie_dynamic
특정 인덱스에서 검색을 수행한 후 그 결과에 해당하는 문서만 삭제하고 싶을 경우 Delete By Query API를 사용하면 됩니다.
# 요청
POST movie_dynamic/_delete_by_query
{
"query": {
"term": {
"movieCd": "20173732"
}
}
}
# 결과
{
"took": 42,
"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,
"throttled_until_millis": 0,
"failures": []
}
5. Update API
스크립트를 바탕으로 문서를 수정할 수 있습니다.(Scripting) 스크립트를 통해 "ctx._source.필드명"과 같은 형태로 접근할 수 있습니다. Update API가 호출되면 엘라스틱서치는 Index에서 문서를 가져와 스크립트를 수행한 후, 이를 다시 재색인(Reindex)합니다. 이러한 원리로 Update API를 사용하기 위해서는 _source 필드가 활성화돼 있어야 하며, ctx 필드에서는 _source 변수뿐 아니라 _index, _type, _id, _version, _routing, _now 등 추가적인 변수도 사용할 수 있습니다.
Update API를 이용해 counter 값을 1만큼 증가시키는 예제입니다.
POST movie_dynamic/_doc/1/_update
{
"script" : {
"source": "ctx._source.counter += params.count",
"lang": "painless",
"params" : {
"count" : 1
}
}
}
# 필드 추가
POST movie_script/_doc/1/_update
{
"script": "ctx._source.movieList.Black_Panther = 3.7"
}
# 필드 제거
POST movie_script/_doc/1/_update
{
"script": "ctx._source.movieList.remove(\"Suits\")"
}
[참고]
엘라스틱서치에서 스크립팅을 사용하는 두 가지 방법이 있습니다.
1) config 폴더에 스크립팅을 저장하는 방식: 스크립트 파일을 config 폴더에 저장한 다음 이름을 지정해 코드에서 호출한다.
2) In-request 방식: 동적 스크립팅이라고 하며 API를 호출할 때 코드 내에서 스크립트를 직접 정의해서 사용한다.
일반적으로 동적 스크립팅 방식이 많이 사용됩니다. 동적 스크립팅 기능을 사용하려면 elasticsearch.yml 파일에 다음과 같은 설정을 추가해야 합니다.
script.disable_dynamic: false
6. Bulk API
Get/Delete/Update API는 한 번에 하나의 문서만을 대상으로 동작합니다. 하지만 Bulk API를 이용하면 한 번의 API 호출로 다수의 문서를 색인하거나 삭제할 수 있습니다. 대량 색인이 필요한 경우 bulk API를 사용하는 것 이 좋습니다. 단, 여러 건의 데이터 처리 중 실패가 발생하더라도 롤백되지 않습니다.
# 요청
POST _bulk
{ "index" : { "_index" : "movie_dynamic", "_type" : "_doc", "_id" : "1" } }
{ "title" : "살아남은 아이" }
{ "delete" : { "_index" : "movie_dynamic", "_type" : "_doc", "_id" : "2" } }
{ "create" : { "_index" : "movie_dynamic", "_type" : "_doc", "_id" : "3" } }
{ "title" : "프렌즈: 몬스터섬의비밀" }
{ "update" : {"_index" : "movie_dynamic", "_type" : "_doc", "_id" : "1"} }
{ "doc" : {"movieNmEn" : "Last Child"} }
# 결과
{
"took": 311,
"errors": false,
"items": [
{
"index": {
"_index": "movie_dynamic",
"_type": "_doc",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1,
"status": 201
}
},
{
"delete": {
"_index": "movie_dynamic",
"_type": "_doc",
"_id": "2",
"_version": 1,
"result": "not_found",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1,
"status": 404
}
},
{
"create": {
"_index": "movie_dynamic",
"_type": "_doc",
"_id": "3",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1,
"status": 201
}
},
{
"update": {
"_index": "movie_dynamic",
"_type": "_doc",
"_id": "1",
"_version": 2,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1,
"status": 200
}
}
]
}
# 요청
GET movie_dynamic/_search
# 결과
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 1,
"hits": [
{
"_index": "movie_dynamic",
"_type": "_doc",
"_id": "1",
"_score": 1,
"_source": {
"title": "살아남은 아이",
"movieNmEn": "Last Child"
}
},
{
"_index": "movie_dynamic",
"_type": "_doc",
"_id": "3",
"_score": 1,
"_source": {
"title": "프렌즈: 몬스터섬의비밀"
}
}
]
}
}
7. Reindex API
Reindex API를 사용하는 가장 일반적인 상황은 한 인덱스에서 다른 인덱스로 문서를 복사할 때 사용합니다.
POST _reindex
{
"source": { # 복사할 인덱스
"index": "movie_dynamic"
},
"dest": { # 복사될 인덱스
"index": "movie_dynamic_new",
"version_type": "internal"
}
}
특정 조회 결과와 일치하는 문서만 복사하고 싶은 경우 source 항목에 쿼리를 포함시키면 됩니다.
POST _reindex
{
"size": 10000, # 기본적으로 Reindex API는 1,000건 단위로 스크롤을 수행
"source": {
"index": "movie_dynamic",
"sort": { #정렬#
"counter": "desc"
}
"type": "_doc",
"query": {
"term": {
"title.keyword": "프렌즈: 몬스터섬의비밀"
}
}
},
"dest": {
"index": "movie_dynamic_new"
}
}