본문 바로가기

공부방/Elasticsearch

CRUD - 입력, 조회, 수정, 삭제

Elasticsearch 커맨드 소개


단일 데이터는 document 이며

인덱스 document의 논리적인 집합을 말합니다.

Elasticsearch에서는 단일 도큐먼트별로 고유한 URL을 갖습니다. 도큐먼트에 접근하는 URL은 아래와 같습니다.

 
http://<호스트>:<포트>/<인덱스>/_doc/<도큐먼트 id>
 
6.x 이전버전 참고
 
http://<호스트>:<포트>/<인덱스>/<도큐먼트 타입>/<도큐먼트 id>

 

인덱스 생성 및 데이터 저장 (PUT)


데이터를 저장하는 경우 인덱스가 존재하지 않는다면, 인덱스가 먼저 생성이 된 후 데이터가 저장됩니다.

PUT을 이용해 데이터를 저장하는 방법은 두가지가 있습니다.

1. 덮어쓰기

2. 덮어쓰기 방지

각각의 방법을 살펴보겠습니다.

 

덮어쓰기 (_doc)

 

기존 데이터가 존재한다면 덮어쓰는 방법입니다.

_doc 이라는 명령어를 이용하여 데이터를 저장하는데 1번 id가 존재한다면 덮어쓰기를 허용한다. 라는 내용입니다.

 

$ curl -XPUT "http://localhost:9200/my_index/_doc/1" -H 'Content-Type: application/json' -d'
{
  "name": "Jongmin Kim",
  "message": "안녕하세요 Elasticsearch"
}'


{"_index":"my_index","_type":"_doc","_id":"1","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":0,"_primary_term":1}

 

덮어쓰기 방지 (_create)

 

기존 데이터가 존재한다면 덮어쓰는 방법입니다.

_doc 이라는 명령어를 이용하여 데이터를 저장하는데 1번 id가 존재한다면 덮어쓰기를 허용한다. 라는 내용입니다.

 

PUT my_index/_create/1
{
  "name":"Jongmin Kim",
  "message":"안녕하세요 Elasticsearch"
}

 

조회 (GET)


 

상세 정보를 보려면 _doc 명령어를 통해서 살펴볼 수 있습니다.

 

GET my_index/_doc/1

 

데이터 정보만 확인하고 싶은 경우 _source 명령어를 사용합니다.

 

GET my_index/_source/1

 

삭제 (DELETE)


 

인덱스의 특정 id에 해당하는 데이터 삭제

 

DELETE my_index/_doc/1

 

인덱스 삭제

 

DELETE my_index

 

 

저장 및 수정 (POST) 


이전에 데이터 저장은 Put을 이용한다고 하였습니다.

PUT을 이용하여 데이터를 저장하는 커맨드를 자세히 살펴보면 id를 지정해주는 것을 확인할 수 있습니다. 반면에 POST로 저장을 하게되면 ID는 자동으로 생성되기 떄문에 따로 지정할 필요가 없습니다.

 

저장 (id 자동 생성)

 

POST 초기 입력에도 사용할 수 있다.

저장할 때 PUT 대신에 POST를 사용할 수 있습니다.

POST 명령어를 사용하여 저장할 때는 ID 값을 입력하지 않습니다.

document id는 저장될 때 자동으로 생성됩니다.

 

POST my_index/_doc
{
  "name":"Jongmin Kim",
  "message":"안녕하세요 Elasticsearch"
}

 

수정 (특정 필드 수정)

 

필드가 여럿 있는 도큐먼트에서 필드 하나만 바꾸기 위해 전체 도큐먼트 내용을 매번 다시 입력하는 것은 번거로운 작업일 것입니다. 이 때는 POST <인덱스>/_update/<도큐먼트 id> 명령을 이용해 원하는 필드의 내용만 업데이트가 가능합니다. 업데이트 할 내용에 "doc" 이라는 지정자를 사용해야 한다는 것을 잊지마세요!

 

POST my_index/_update/1
{
  "doc": {
    "message":"안녕하세요 Kibana"
  }
}

 

BULK 명령어


여러가지 명령어를 한꺼번에 실행하는 경우를 말합니다.

명령문과 데이터문은 반드시 한 줄 안에 입력이 되어야 하며 줄바꿈을 허용하지 않습니다.

단건으로 색인하는 것 보다 10배 정도 속도 차이가 나기 때문에 대용량 데이터 색인은 bulk index를 쓰는것이 좋습니다.

 

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"}}

 

검색 (GET)


Elasticsearch의 진가는 쿼리를 통한 검색 기능에 있습니다.

검색은 인덱스 단위로 이루어집니다.

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

 

검색은 두가지 방법이 있습니다.

  1. URI 검색
  2. databody 검색

 

URI 검색

 

_search 뒤에 q 파라메터를 사용해서 검색어를 입력할 수 있습니다. 이렇게 요청 주소에 검색어를 넣어 검색하는 방식을 URI 검색이라고 합니다.
앞에서 만든 test 인덱스에서 "value" 라는 값을 검색하기 위해서는 다음과 같이 입력합니다.
 
 
GET test/_search?q=value

 

결과를 보면 hits.total.value 부분에 검색 결과 전체에 해당되는 문서의 개수가 표시되고 다시 그 안의 hits:[ ] 구문 안에 배열로 가장 정확도가 높은 문서 10개가 나타납니다. 이 정확도를 relevancy(렐러번시 라고 읽습니다) 라고 하며 뒤에서 다시 설명하도록 하겠습니다.
두 개의 검색어 "value" 그리고 "three"AND 조건으로 검색 하려면 다음과 같이 입력합니다. URI 쿼리에서는 AND, OR, NOT 의 사용이 가능하며 반드시 모두 대문자로 입력해야합니다.
 
 
검색 예제 1
 
GET test/_search?q=value AND three

 

검색 예제 2

 

// field 값에 value와 three 둘다 들어있는 결과를 검색
GET test/_search?q=field:three AND file:value

 

Databody (query) 검색

 

실제로는 대부분 query문을 사용합니다.

 

GET test/_search
{
  "query": {
    "match": {
      "field": "value"
    }
  }
}

 

멀티테넌시 (Multitenancy)


  1. Elasticsearch는 여러 개의 인덱스를 한꺼번에 묶어서 검색할 수 있는 멀티테넌시를 지원합니다.
  2. logs-2018-01, logs-2018-02 … 와 같이 날짜별로 저장된 인덱스들이 있다면 이 인덱스들을 모두 logs-*/_search 명령으로 한꺼번에 검색이 가능합니다.
  3. 특히 시간순으로 따라 쌓이는 로그 데이터를 다룰 때는 인덱스를 일단위 등으로 구분하는것이 좋습니다.
  4. 나중에 필드 구조가 변경되거나 크기가 커져서 샤드 설정을 변경하거나 할 때 더욱 용이합니다.

 

여러 인덱스를 검색할때는 쉼표, 로 나열하거나 와일드카드 * 문자로 묶을 수 있습니다.
쉼표로 나열해서 여러 인덱스 검색
 
GET logs-2018-01,2018-02,2018-03/_search
 

 

와일드카드 * 를 이용해서 여러 인덱스 검색
 
GET logs-2018-*/_search
 

 

인덱스명 대신 _all 지정자를 사용하여 GET _all/_search 와 같이 실행하면 클러스터에 있는 모든 인덱스를 대상으로 검색이 가능합니다. 하지만 _all은 시스템 사용을 위한 인덱스 같은 곳의 데이터까지 접근하여 불필요한 작업 부하를 초래하므로 _all 은 되도록 사용하지 않도록 합니다.
 

검색에 대한 부분은 다음 글에서 추가적으로 더욱 자세하게 살펴보도록 하겠습니다.

 

 

'공부방 > Elasticsearch' 카테고리의 다른 글

정확도 - Relevancy (Score 책정)  (0) 2023.05.10
검색과 쿼리 - Query DSL (domain specific language)  (0) 2023.05.10
인덱스와 샤드  (0) 2023.05.10
pm2를 이용한 데몬 실행  (0) 2023.05.09
Kibana  (0) 2023.05.09