시작하세요! 엘라스틱서치 정리한 글 입니다.

데이터 처리

데이터 구조

인덱스(index) > 타입(type) > 도큐먼트(document) 단위로 이루어 진다. 서로 다른 인덱스와 타입들은 다른 매핑 구조로 구성되며 각각 다른 공간에 저장되고 처리된다. _all 명령어나 와일드카드 질의 등으로 여러 개의 인덱스를 한꺼번에 묶어 검색하거나 처리할 수 있다.

관계형 DB 엘라스틱 서치
데이터베이스(Database) 인덱스(Index)
테이블(Table) 타입(Type)
열(Row) 도큐먼트(Document)
행(Column) 필드(Field)
스키마(Schema) 매핑(Mapping)

엘라스틱 서치의 REST API를 이용한 curl 명령은 다음과 같은 형식으로 사용한다.

curl -X(메서드) http://host:port/{인덱스}/{타입}/{도큐먼트id} -d '{JSON 데이터}'

HTTP Method CRUD SQL
GET Read Select
PUT Update Update
POST Create Insert
DELETE Delete Delete

데이터 입력

PUT 메서드를 이용해 입력한다.

$ curl -XPUT 'http://localhost:9200/books/book/1' -H 'Content-Type: application/json' -d '
{
"title":"Elasticsearch Guide",
"author":"Kim",
"date":"2014-05-01",
"pages":250
}'
{"_index":"books","_type":"book","_id":"1","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":0,"_primary_term":1}

# 데이터 확인
$ curl -XGET 'localhost:9200/books/book/1?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "1",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "title" : "Elasticsearch Guide",
    "author" : "Kim",
    "date" : "2014-05-01",
    "pages" : 250
  }
}

POST 메서드를 이용해 도큐먼트 id를 생략하고 입력할 수도 있다. 이 경우 자동으로 임의의 id(UtHje2cBF4s6Kti3QweG)가 생성된다.

$ curl -XPOST 'localhost:9200/books/book' -H 'Content-Type: application/json' -d '
{
  "title":"Elasticsearch Guide",
  "author":"Kim",
  "started":"2014-05-1",
  "pages":250
}'
{"_index":"books","_type":"book","_id":"UtHje2cBF4s6Kti3QweG","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":0,"_primary_term":2}

다시 한번 PUT 메서드를 이용해 업데이트한다. 데이터가 수정됐으므로 _version 필드의 값이 증가한다. 도큐먼트가 업데이트 될 때 _version 필드에서 변경된 횟수를 파악할 수 있다. 도큐먼트 버전은 확인할 수 있지만, 기존 도큐먼트는 보관되지 않고 업데이트할 때마다 삭제되고 새로 쓰인다. 한 번 업데이트한 도큐먼트는 이전 버전으로 되돌릴 수 없으므로 중요한 데이터를 다룰 때에는 업데이트에 주의해야 한다.

$ curl -XPUT 'http://localhost:9200/books/book/1' -H 'Content-Type: application/json' -d '
{
"title":"Elasticsearch Guide",
"author":["Kim", "Lee"],
"date":"2014-05-01",
"pages":300
}'
{"_index":"books","_type":"book","_id":"1","_version":4,"result":"updated","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":3,"_primary_term":2}

실제로 입력한 JSON 데이터는 도큐먼트의 _source 필드에 JSON 형식의 문자열로 저장된다. 메타 정보를 제외한 _source 필드의 값만 보려면 도큐먼트 URI 뒤에 _source를 추가한다.

$ curl -XGET 'localhost:9200/books/book/1?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "1",
  "_version" : 4,
  "found" : true,
  "_source" : {
    "title" : "Elasticsearch Guide",
    "author" : [
      "Kim",
      "Lee"
    ],
    "date" : "2014-05-01",
    "pages" : 300
  }
}

$ curl -XGET 'localhost:9200/books/book/1/_source?pretty'
{
  "title" : "Elasticsearch Guide",
  "author" : [
    "Kim",
    "Lee"
  ],
  "date" : "2014-05-01",
  "pages" : 300
}

데이터 삭제

삭제는 DELETE 메서드를 이용한다. 도큐먼트를 삭제한다.

$ curl -XDELETE 'localhost:9200/books/book/1' -H 'Content-Type: application/json'
{"_index":"books","_type":"book","_id":"1","_version":5,"result":"deleted","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":4,"_primary_term":2}

# 데이터 확인
$ curl -XGET 'localhost:9200/books/book/1?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "1",
  "found" : false
}

도큐먼트 데이터를 삭제하더라도 도큐먼트의 메타 정보는 여전히 남아있다. 위와 동일한 URI에 데이터를 입력해보면 _version 값이 변하는 것을 확인할 수 있다. 도큐먼트 삭제는 도큐먼트가 실제로 삭제되는 것이 아니라 도큐먼트의 _source에 입력된 데이터 값이 빈 값으로 업데이트되고 검색되지 않게 상태가 변경되는 것으로 이해하는 것이 편하다.

$ curl -XPOST 'localhost:9200/books/book/1' -H 'Content-Type: application/json' -d '
{
  "title":"Elasticsearch Guide",
  "author":["Kim","Lee"],
  "started":"2014-05-1",
  "pages":300
}'
{"_index":"books","_type":"book","_id":"1","_version":3,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":7,"_primary_term":2}

DELETE 메서드를 사용한 삭제 명령은 인덱스 단위로도 사용할 수 있다. 인덱스 단위로 삭제하면 해당 인덱스에 포함된 타입, 도큐먼트가 모두 삭제되며 URI에 접근이 불가능하게 된다. 인덱스 삭제 후 도큐먼트 데이터를 조회하면 인덱스를 찾을 수 없다는 메시지가 출력된다.

$ curl -XDELETE 'localhost:9200/books' -H 'Content-Type: application/json'
{"acknowledged":true}

$ curl -XGET 'localhost:9200/books/book/1?pretty'
{
  "error" : {
    "root_cause" : [
      {
        "type" : "index_not_found_exception",
        "reason" : "no such index",
        "resource.type" : "index_expression",
        "resource.id" : "books",
        "index_uuid" : "_na_",
        "index" : "books"
      }
    ],
    "type" : "index_not_found_exception",
    "reason" : "no such index",
    "resource.type" : "index_expression",
    "resource.id" : "books",
    "index_uuid" : "_na_",
    "index" : "books"
  },
  "status" : 404
}

데이터 업데이트(_update) API

도큐먼트 데이터의 업데이트는 _update API의 두 개의 매개 변수 docscript를 이용해서 데이터를 제어할 수 있다. 우선 doc 매개변수를 사용해서 필드와 필드의 값을 추가해보자.

# 데이터 생성
$ curl -XPOST 'localhost:9200/books/book/1' -H 'Content-Type: application/json' -d '
{
  "title":"Elasticsearch Guide",
  "author":"Kim",
  "started":"2014-05-1",
  "pages":250
}'
{"_index":"books","_type":"book","_id":"1","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":0,"_primary_term":1}

# 데이터 확인
$ curl -XGET 'localhost:9200/books/book/1?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "1",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "title" : "Elasticsearch Guide",
    "author" : "Kim",
    "started" : "2014-05-1",
    "pages" : 250
  }
}

# 데이터 업데이트
$ curl -XPOST 'localhost:9200/books/book/1/_update' -H 'Content-Type: application/json' -d '
{
"doc":{"category":"ICT"}
}'
{"_index":"books","_type":"book","_id":"1","_version":2,"result":"updated","_shards":{"total":2,"successful":1,"fai
led":0},"_seq_no":1,"_primary_term":1}

$ curl -XGET 'localhost:9200/books/book/1?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "1",
  "_version" : 2,
  "found" : true,
  "_source" : {
    "title" : "Elasticsearch Guide",
    "author" : "Kim",
    "started" : "2014-05-1",
    "pages" : 250,
    "category" : "ICT"
  }
}

_update API는 도큐먼트의 구조를 변경하는 것이 아니라 실제로는 GET 메서드로 저장된 도큐먼트의 값을 가져와서 입력한 명령을 토대로 새로 변경된 도큐먼트 내용을 만들고 다시 그 내용을 기존 도큐먼트에 입력하는 방식으로 동작한다.

이번에는 doc 매개 변수를 사용해서 기존 필드에 저장된 값을 변경해보자.

$ curl -XPOST 'localhost:9200/books/book/1/_update' -H 'Content-Type: application/json' -d '
{
"doc":{"author":"Lee"}
}'
{"_index":"books","_type":"book","_id":"1","_version":3,"result":"updated","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":2,"_primary_term":1}

$ curl -XGET 'localhost:9200/books/book/1?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "1",
  "_version" : 3,
  "found" : true,
  "_source" : {
    "title" : "Elasticsearch Guide",
    "author" : "Lee",
    "started" : "2014-05-1",
    "pages" : 250,
    "category" : "ICT"
  }
}

script 매개 변수를 사용하면 _source에 있는 도큐먼트의 내용에 다양한 연산을 적용할 수 있다. _source에 있는 도큐먼트 내용을 변경하려면 scriptctx._source 명령을 사용한다.

$ curl -XPOST 'localhost:9200/books/book/1/_update' -H 'Content-Type: application/json' -d '
{
  "script": {
    "source": "ctx._source.pages+=5"
  }
}'
{"_index":"books","_type":"book","_id":"1","_version":4,"result":"updated","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":3,"_primary_term":1}

# 데이터 확인
$ curl -XGET 'localhost:9200/books/book/1?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "1",
  "_version" : 4,
  "found" : true,
  "_source" : {
    "title" : "Elasticsearch Guide",
    "author" : "Lee",
    "started" : "2014-05-1",
    "pages" : 300,
    "category" : "ICT"
  }
}

script 매개 변수를 사용해서 문자 필드를 수정해보자. 먼저 추가하려는 값을 특정 변수에 저장하고 연산을 이용해 추가한다.

# 1. 문자열 추가
$ curl -XPOST 'localhost:9200/books/book/1/_update' -H 'Content-Type: application/json' -d '{
"script":{
    "source":"ctx._source.author+=params.new_author",
    "params":{
        "new_author":"Kim"
        }
    }
}'
{"_index":"books","_type":"book","_id":"1","_version":8,"result":"updated","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":7,"_primary_term":1}

# 확인
$ curl -XGET 'localhost:9200/books/book/1?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "1",
  "_version" : 8,
  "found" : true,
  "_source" : {
    "title" : "Elasticsearch Guide",
    "author" : "LeeKim",
    "started" : "2014-05-1",
    "pages" : 305,
    "category" : "ICT"
  }
}

# author 필드를 배열로 변경
$ curl -XPOST 'localhost:9200/books/book/1/_update' -H 'Content-Type: application/json' -d '
{
"doc":{"author":["Lee"]}
}'
{"_index":"books","_type":"book","_id":"1","_version":5,"result":"updated","_shards":{"total":2,"successful":1,"fai
led":0},"_seq_no":4,"_primary_term":1}

# 2. 배열 추가
$ curl -XPOST 'localhost:9200/books/book/1/_update' -H 'Content-Type: application/json' -d '{
"script":{
    "source":"ctx._source.author.add(params.new_author)",
    "params":{
        "new_author":"Kim"
        }
    }
}'
{"_index":"books","_type":"book","_id":"1","_version":11,"result":"updated","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":10,"_primary_term":1}

# 확인
$ curl -XGET 'localhost:9200/books/book/1?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "1",
  "_version" : 11,
  "found" : true,
  "_source" : {
    "title" : "Elasticsearch Guide",
    "author" : [
      "Lee",
      "Kim"
    ],
    "started" : "2014-05-1",
    "pages" : 300,
    "category" : "ICT"
  }
}

이번에는 if 문을 이용한 조건문을 처리해보자. author 필드의 값에 “Kim”이 포함된 경우 pages 필드 값을 100으로, 포함되지 않은 경우 200으로 바꾸는 명령이다.

$ curl -XPOST 'localhost:9200/books/book/1/_update' -H 'Content-Type: application/json' -d '{
"script":{
  "source":"if(ctx._source.author.contains(params.auth)) {ctx._source.pages=100} else {ctx._source.pages=200}",
  "params": {
    "auth":"Kim"
    }
  }
}'
{"_index":"books","_type":"book","_id":"1","_version":12,"result":"updated","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":11,"_primary_term":1}

$ curl -XGET 'localhost:9200/books/book/1?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "1",
  "_version" : 12,
  "found" : true,
  "_source" : {
    "title" : "Elasticsearch Guide",
    "author" : [
      "Lee",
      "Kim"
    ],
    "started" : "2014-05-1",
    "pages" : 100,
    "category" : "ICT"
  }
}

파일을 이용한 데이터 처리

입력할 데이터의 내용을 미리 파일에 기록한 뒤 다음과 같이 @{파일명}을 지정하는 형식으로도 입력할 수 있다.

curl -X(메서드) http://host:port/{인덱스}/{타입}/{도큐먼트id} -d @{파일명}

$ pwd
~/Project
$ mkdir start-elasticsearch
$ cd start-elasticsearch

# 파일생성
$ echo '{
  "title":"Elasticsearch Guide",
  "author":["Kim", "Lee"],
  "date":"2014-05-01",
  "pages":300
}' > book1

# 파일을 이용해 데이터 생성
$ curl -XPUT 'http://localhost:9200/books/book/1' -H 'Content-Type: application/json' -d @book1
{"_index":"books","_type":"book","_id":"1","_version":3,"result":"updated","_shards":{"total":2,"successful":1,"fai
led":0},"_seq_no":2,"_primary_term":1}

$ curl -XGET 'localhost:9200/books/book/1?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "1",
  "_version" : 3,
  "found" : true,
  "_source" : {
    "title" : "Elasticsearch Guide",
    "author" : [
      "Kim",
      "Lee"
    ],
    "date" : "2014-05-01",
    "pages" : 300
  }
}

이번에는 파일과 _update API를 이용해 데어터를 업데이트해보자.

# 파일 생성
$ echo '{
"doc": {
  "category":"ICT"
}}' > update_1

$ curl -XPOST 'localhost:9200/books/book/1/_update' -H 'Content-Type: application/json' -d @update_1
{"_index":"books","_type":"book","_id":"1","_version":4,"result":"updated","_shards":{"total":2,"successful":1,"fai
led":0},"_seq_no":3,"_primary_term":1}

$ curl -XGET 'localhost:9200/books/book/1?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "1",
  "_version" : 4,
  "found" : true,
  "_source" : {
    "title" : "Elasticsearch Guide",
    "author" : [
      "Kim",
      "Lee"
    ],
    "date" : "2014-05-01",
    "pages" : 300,
    "category" : "ICT"
  }
}

벌크(_bulk) API를 이용한 배치 작업

여러 명령을 한꺼번에 실행할 수 있는 배치 작업을 위한 벌크(_bulk) API를 제공한다. 입력할 데이터를 모아 한꺼번에 처리하므로 데이터를 각각 처리하고 결과를 반환할 때보다 속도가 매우 빠르다.

curl -XPOST http://host:port/{인덱스}/{타입}/_bulk -d '{JSON 데이터}' 또는 @{파일명}

curl -XPOST http://host:port/{인덱스}/_bulk -d '{JSON 데이터}' 또는 @{파일명}

curl -XPOST http://host:port/_bulk -d '{JSON 데이터}' 또는 @{파일명}

벌크 API는 index, create, delete, update의 4가지 동작을 처리할 수 있다. delete를 제외한 index, create, update 동작은 실행 메타 정보(action meta data)와 요청 데이터(request body)가 각각 한 쌍씩 묶여 동작한다. delete 동작은 삭제할 도큐먼트의 실행 메타 정보만 필요로 하므로 요청 데이터는 입력하지 않는다.

실행 메타 정보는 {동작 {인덱스, 타입, 도큐먼트 id}} 형식으로 입력한다. id는 생략할 수 있으며 생략하면 임의의 문자열이 id로 저장된다. 주의할 점은 실행 메타 정보와 요청 데이터는 한줄로 입력해야 하며 각 입력이 끝날 때마다 반드시 줄 바꿈을 해야 한다.

{"index": {"_index":"books", "_type":"book", "_id":1}}  //index 실행 메타 정보
{"field":"value"}  // index 요청 데이터

{"delete": {"_index":"books", "_type":"book", "_id":1}}  // delete 실행 메타 정보

{"create": {"_index":"books", "_type":"book", "_id":1}}  // create 실행 메타 정보
{"field":"value"}  // create 요청 데이터

{"update": {"_index":"books", "_type":"book", "_id":1}}  // update 실행 메타 정보
{"doc": {"field":"value"}}  // update 요청 데이터

index와 create 모두 데이터를 입력하는 명령이다. 다만 도큐먼트가 이미 존재할 때 create 명령을 사용하면 입력 오류가 발생한다. index 명령은 기존에 도큐먼트가 존재하면 입력하는 데이터로 기존 도큐먼트를 덮어쓰게 된다.

$ curl -XPOST 'localhost:9200/_bulk' -H 'Content-Type: application/json' -d '
{"index":{"_index":"books", "_type":"book", "_id":"1"}}
{"title":"Elasticsearch Guide", "author":"Kim", "pages":250}
{"index":{"_index":"books", "_type":"book", "_id":"2"}}
{"title":"Elasticsearch Easy Guide", "author":"Lee", "pages":300}
'
{"took":40,"errors":false,"items":[{"index":{"_index":"books","_type":"book","_id":"1","_version":5,"result":"updated","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":4,"_primary_term":1,"status":200}},{"index":{"_index":"books","_type":"book","_id":"2","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":0,"_primary_term":1,"status":201}}]}

$ curl -XGET 'localhost:9200/books/book/1?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "1",
  "_version" : 5,
  "found" : true,
  "_source" : {
    "title" : "Elasticsearch Guide",
    "author" : "Kim",
    "pages" : 250
  }
}

$ curl -XGET 'localhost:9200/books/book/2?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "2",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "title" : "Elasticsearch Easy Guide",
    "author" : "Lee",
    "pages" : 300
  }
}

처리할 동작이 많을 때는 명령을 일일이 입력하는 방법보다는 파일에 입력해 놓고 벌크를 이용해 처리하는 방법이 훨씬 효과적이다. 벌크 파일은 바이너리로 처리해야 하므로 데이터 옵션을 -d가 아닌 --data-binary로 해야 한다.

$ vi bulk_1
{"delete":{"_index":"books", "_type":"book", "_id":"1"}}
{"update":{"_index":"books", "_type":"book", "_id":"2"}}
{"doc":{"date":"2014-05-01"}}
{"create":{"_index":"books", "_type":"book", "_id":"3"}}
{"title":"Elasticsearch Guide 2", "author":"Park", "pages":400}

$ curl -XPOST 'localhost:9200/_bulk?pretty' -H 'Content-Type: application/json' --data-binary @bulk_1
{
  "took" : 72,
  "errors" : false,
  "items" : [
    {
      "delete" : {
        "_index" : "books",
        "_type" : "book",
        "_id" : "1",
        "_version" : 6,
        "result" : "deleted",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 5,
        "_primary_term" : 1,
        "status" : 200
      }
    },
    {
      "update" : {
        "_index" : "books",
        "_type" : "book",
        "_id" : "2",
        "_version" : 2,
        "result" : "updated",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 1,
        "_primary_term" : 1,
        "status" : 200
      }
    },
    {
      "create" : {
        "_index" : "books",
        "_type" : "book",
        "_id" : "3",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 0,
        "_primary_term" : 1,
        "status" : 201
      }
    }
  ]
}

# 데이터 확인
$ curl -XGET 'localhost:9200/books/book/1?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "1",
  "found" : false
}

# 데이터 확인
$ curl -XGET 'localhost:9200/books/book/2?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "2",
  "_version" : 2,
  "found" : true,
  "_source" : {
    "title" : "Elasticsearch Easy Guide",
    "author" : "Lee",
    "pages" : 300,
    "date" : "2014-05-01"
  }
}

# 데이터 확인
$ curl -XGET 'localhost:9200/books/book/3?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "3",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "title" : "Elasticsearch Guide 2",
    "author" : "Park",
    "pages" : 400
  }
}

벌크 API를 사용할 때 URI에 인덱스, 타입 수준까지 명시하면 벌크 데이터의 실행 메타 정보에 인덱스, 타입을 생략할 수 있다. 실행 메타 정보에 타입과 id만 명시하면 된다.

$ curl -XPOST 'localhost:9200/books/book/_bulk?pretty' -H 'Content-Type: application/json' -d '
{"index": {"_id":"1"}}
{"title":"Elasticsearch Guide", "author":"Kim", "pages":250}
'
{
  "took" : 25,
  "errors" : false,
  "items" : [
    {
      "index" : {
        "_index" : "books",
        "_type" : "book",
        "_id" : "1",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 6,
        "_primary_term" : 1,
        "status" : 201
      }
    }
  ]
}

# 확인
$ curl -XGET 'localhost:9200/books/book/1?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "1",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "title" : "Elasticsearch Guide",
    "author" : "Kim",
    "pages" : 250
  }
}

# id 없이 생성
$ curl -XPOST 'localhost:9200/books/book/_bulk?pretty' -H 'Content-Type: application/json' -d '
{"index": {}}
{"title":"Elasticsearch Guide", "author":"Kim", "pages":250}
'
{
  "took" : 54,
  "errors" : false,
  "items" : [
    {
      "index" : {
        "_index" : "books",
        "_type" : "book",
        "_id" : "yzN9nWcBBtTGuTMCz_Q6",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 2,
        "_primary_term" : 2,
        "status" : 201
      }
    }
  ]
}

# 확인
$ curl -XGET 'localhost:9200/books/book/yzN9nWcBBtTGuTMCz_Q6?pretty'
{
  "_index" : "books",
  "_type" : "book",
  "_id" : "yzN9nWcBBtTGuTMCz_Q6",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "title" : "Elasticsearch Guide",
    "author" : "Kim",
    "pages" : 250
  }
}

벌크 API를 이용한 배치 작업의 성능과 한계는 엘라스틱서치가 설치된 시스템 하드웨어의 영향을 받는다. 통상적으로 1,000~5,000개 정도의 작업을 한 배치로 실행하는 것이 바람직하며 10,000개 이상의 작업을 배치로 실행하면 오류가 발생할 확률이 높다.