Lined Notebook

Elasticsearch 데이터 처리

by HeshAlgo

Elasticsearch는 http 프로토콜로 접근이 가능한 REST API를 지원합니다.

자원별로 고유 URL로 접근이 가능하며 http 메서드 PUT, POST, GET, DELETE를 이용해서 자원을 처리합니다.

 

Elasticsearch에서는 단일 도큐먼트별로 고유한 URL을 갖고있습니다. 

http://<호스트>:<포트>/<인덱스명>/_doc/<도큐먼트 Id>

 

1. 입력(PUT)

데이터를 입력할 때는 PUT 메서드를 이용합니다. 다음 my_index에서 도큐먼트가 1인 데이터를 입력하는 방식입니다.

PUT my_index/_doc/1

{
  "name" : "Gildong Hong" ,

  "message" : "안녕하세요."

}

// my_index/_doc/1 최초 입력 결과

{
  "_index" : "my_index",

  "_type" : "_doc",

  "_id" : "1",

  "_version" : 1,

  "result" : "created",

  "_shards" : " {

      "total" : 2,

      "successful" : 1,

      "failed" : 0

 },

  "_seq_no" : 0,

  "_primary_term" : 1

}

처음 도큐먼트를 입력하면 결과에 "result" : "created"로 표시가 됩니다. 동일한 URL에 다른 내용의 도큐먼틀를 다시 입력하게 되면 기존 도큐먼트는 삭제되고 새로운 도큐먼트로 덮어씌어지게 됩니다. 이때는 결과에 'created'가 아닌 'updated'가  표시 됩니다. 실수로 기존 도큐먼트가 덮어 씌어지는것을 방지하기 위해서는 입력 명령에 _doc 대신 _create를 사용해서 새로운 도큐먼트의 입력만 허용하는것이 가능합니다. 만약 기존에 있는 도큐먼트를 새로 생성한다 하면 409에러가 나타날 것입니다.

 

2. 조회(GET)

GET 메서드로 가져올 도큐먼트의 URL을 입력하면 도큐먼트의 내용을 가져옵니다. _doc대신 _source를 사용하면 해당 source내용만 보실수 있습니다.

GET my_index/_doc/1

 

3. 삭제 (DELETE)

DELETE 메서드를 이용해서 도큐먼트 또는 인덱스 단위의 삭제가 가능합니다. 

DELETE my_index/_doc/1 명령으로 도큐먼트를 삭제하면 "result" : "deleted" 결과가 리턴됩니다.

도큐먼트가 삭제되었지만 인덱스는 남아있는 경우 삭제된 도큐먼트를 GET해서 가져오려 한다면 해당 도큐먼트를 찾지 못했다는 "found" : false 응답을 받습니다.

DELETE my_index를 할 경우 전체 인덱스가 삭제됩니다.

// 도큐먼트 삭제

DELETE my_index/_doc/1

// 인덱스 삭제

DELETE my_index

 

4. 수정 (POST)

POST 메서드는 PUT 메서드와 유사하게 데이터 입력에 사용이 가능합니다. 도큐먼트를 입력할 때 POST 메서드로 <인덱스>/_doc 까지만 입력하게 되면 자동으로 임의의 도큐먼트 Id가 생성됩니다. 도큐먼트 id의 자동생성은 PUT 메서드로는 동작하지 않습니다. 

 

5. _update

입력된 도큐먼트를 수정하기 위해서 기존 도큐먼트의 URL에 변경될 내용의 도큐먼트 내용을 다시 PUT 하는것으로 대치가 가능하지만 필드가 여러개 있는 도큐먼트에서 필드 하나만 바꾸기 위해 전체 도큐먼트 내용을 매번 다시 입력해야하는 작업은 번거로운 일입니다. 

이때는 POST <인덱스명>/_update/<도큐먼트 id> 명령을 이용해 원하는 필드의 내용만 업데이트가 가능합니다. 

POST my_index/_update/1

{
  "doc": {
    "message": "안녕하세요 Elasticsearch"
  }
}

1) _update 동작과정

_update API를 사용해서 단일 필드만 수정하는 경우에도 실제로 내부에서는 도큐먼트 전체 내용을 가져와서 _doc에서 지정한 내용을 변경한 새 도큐먼트로 만든 뒤 전체 내용을 다시 PUT으로 입력하는 작업입니다.

 

6. 벌크 API(Bulk API)

여러가지 명령을 한꺼번에 실행을 할때 사용하게 됩니다. 
_bulk API로 index, create, update, delete의 동작이 가능하며 delete를 제외하고는 명령문과 데이터문을 한 줄씩 순서대로 입력해야 합니다. 줄바꿈은 이루어지면 안됩니다. 

POST _bulk

{"index":{"_index":"test", "_id":"1"}}
{"field":"value one"}
{"index":{"_index":"test""_id":"2"}}
{"field":"value two"}
{"delete":{"_index":"test""_id":"2"}}
{"create":{"_index":"test""_id":"3"}}
{"field":"value three"}
{"update":{"_index":"test""_id":"1"}}
{"doc":{"field":"value two"}}

각각의 명령문들과 데이터문들은 아래와 같은 뜻을 나타냅니다.

{"index":{"_index":"test""_id":"1"}} -> test/_doc/1에 {"field":"value one"}입력

{"index":{"_index":"test""_id":"2"}} -> test/_doc/2에 {"field":"value two"} 입력

{"delete":{"_index":"test""_id":"2"}} -> test/_doc/2 삭제

{"create":{"_index":"test""_id":"3"}} -> test/_doc/3에 {"field":"value three"} 입력

{"update":{"_index":"test""_id":"1"}} -> test/_doc/1 도큐먼트를 {"doc":{"field":"value two"}}로 수정

 

모든 명령이 동일한 인덱스에서는 아래와 같이 사용이 가능합니다.

POST test/_bulk

{"index":{"_id":"1"}}
{"field":"value one"}
{"index":{"_id":"2"}}
{"field":"value two"}
{"delete":{"_id":"2"}}
{"create":{"_id":"3"}}
{"field":"value three"}
{"update":{"_id":"1"}}
{"doc":{"field":"value two"}}

벌크 동작은 따로따로 수행하는것보다 속도가 훨씬 빠르기 때문에 대량의 데이터를 입력할 때는 반드시 _bulk API를 사용해야 불필요한 오버헤드가 없습니다. 

 

7. 검색 API(Search API)

검색은 인덱스 단위로 이루어지며 GET <인덱스명>/_search 형식으로 사용합니다. 쿼리를 입력하지 않으면 전체 도큐먼트를 찾는 match_all 검색을 합니다.

 

1) URI 검색

_search 뒤에 q 파라미터를 사용해서 검색어를 입력할 수 있습니다. 이렇게 요청 주소에 검색어를 넣어 검색하는 방식을 URI 검색이라고 합니다. 

GET test/_search?q=value

해당 명령어 입력후 결과를 보면 htis.total.value 부분에 검색 결과 전체에 해당되는 문서의 개수가 표시되고 다시 그 안의 hit:[ ] 구문 안에 배열로 가장 정확도가 높은 문서 10개가 나타납니다. 

URI 쿼리에서는 AND, OR, NOT의 사용이 가능하며 반드시 모두 대문자로 입력해야 합니다.

GET test/_search?q=value AND three

 

2) 데이터 본문(Data Body) 검색

데이터 쿼리를 데이터 본문으로 입력하는 방식입니다. Elasticsearch의 QueryDSL을 사용하며 쿼리 또한 JSON 형식으로 되어있습니다.

가장 많이 사용되는 것은 match 쿼리이며 여기서는 문법만 살펴보겠습니다. 데이터 본문 검색으로 field 필드 값이 value인 도큐먼트를 검색하기 위해서는 아래와 같이 명령어를 실행합니다.

GET my_index

{
  "query" : {
    "match" : {

      "field" : "value"

    }
  }
}

 

참고 문헌 😶

https://esbook.kimjmin.net/

'Elasticsearch' 카테고리의 다른 글

[Elasticsearch] curl: (52) Empty reply from server  (0) 2022.10.02
검색과 쿼리 - Query DSL (2)  (0) 2022.05.28
데이터 모델링 (1) - Settings, Mappings  (0) 2022.01.21
Elasticsearch Node  (0) 2021.12.23
Elasticsearch에 대해서  (0) 2021.12.20

블로그의 정보

꾸준히 공부하는 개발 노트

HeshAlgo

활동하기