BackEnd/Elasticsearch

09. 문서관리 API(Document API)

hanseom 2021. 9. 24. 18:50
반응형

엘라스틱서치에서 제공하는 대표적인 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"
  }
}

 

반응형