DB/ElasticSearch

[ElasticSearch] 엘라스틱서치 ( elasticsearch ) 인덱스 생성, CRUD , ...

HMHA 2023. 2. 9. 11:55
300x250
반응형

#엘라스틱서치 ( #elasticsearch ) 에 #인덱스 를 생성하고 #매핑 을 설정한 후 실제로 데이터를 insert, delete, select 등을 해봅시다.

엘라스틱서치가 DB 이지만 일반 DB와 다른 용어를 사용하기에 용어정리를 잠깐 하겠습니다.

일반 RDB
엘라스틱서치 
비고
Database, table
index , type
일반 RDB는 하나의 Database 내에 여러개의 table을 가질수 있으나,
엘라스틱서치 6 (?)부터는 index당 오직 하나의 type 만 가질수 있습니다.
엘라스틱서치 7 에서는 일부 명령어에 type 부분을 생략하는게 디폴트로 되어 있습니다.
row
document
 
column
field
 
schema
mapping
name: varchar
age: int64
위와 같이 각 필드별 데이터 타입을 지정한걸 매핑이라고 합니다.
엘라스틱서치는 스키마 세팅없이 데이터를 insert 하면
해당 데이터를 체크해서 자동으로 스키마가 생성되나,
100% 정확하지 않기에 수동으로 매핑을 설정하는걸 권장합니다.

처음 엘라스틱서치를 접하면 위 용어들이 너무 헷갈립니다. 저는 포스트잇에 위 표를 적절히 적어서 모니터옆에 놔두고 헷갈릴때마다 보곤 했습니다.

자, 이제 본격적으로 데이터 관련 작업을 해봅시다. 참고로 저는 엘라스틱서치 7.4 를 설치하고 테스트했습니다. 그 이하 버전과 일부 명령이 호환되지 않을수 있습니다. 대표적인게 type 에 기본으로 _doc 를 쓰는데, 버전 7부터는 _doc 를 적으니 에러가 나는 경우가 있습니다. 이 부분만 여러분의 엘라스틱서치 버전과 차이날 수 있으니 참고하세요.

우선 데이터를 넣을 인덱스를 생성하도록 합니다.

#키바나#dev #tool 에서 아래처럼 입력합니다.

movie 라는 이름의 인덱스를 생성하고, 샤드와 레플리카는 1개씩, name, year, genre 라는 필드를 text, integer, keyword 타입으로 지정하여 인덱스를 생성하라는 뜻입니다. ( 엘라스틱서치 6이하에서는 mappings 아래에 _doc 가 있어야 하나, 버전 7 부터는 _doc 라는 type명을 지정하지 않는게 디폴트입니다. 인덱스당 오직 하나의 type만 가지기에 굳이 type명을 지정할 필요가 없어서가 아닐까요? )

 

PUT /movie
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1
  },
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "year": {
        "type": "integer"
      },
      "genre": {
        "type": "keyword"
      }
    }
  }
}

integer 야.. 숫자형이다 라고 금방 알텐데, keyword 와 text 의 차이는 궁금할겁니다.

keyword는 형태소 분석이 불필요한, 단어 자체가 의미가 있는 경우이고, text 는 형태소 분석이 필요한 경우입니다.

장르의 경우, 액션, 멜로, 호러 등과 같은 값이 들어갈 수 있고,

영화 이름의 경우, "왕좌의 게임", "반지의 제왕", "쥬라기 공원" 과 같이 여러 단어들의 조합으로 구성되고, 검색시 "게임" 이라고만 검색해도 "왕좌의 게임" 이 검색되어야 하는 경우입니다.

당연히 text 타입이 full 로 단어를 적지 않아도 검색이 되니, 이게 더 많은 기능을 가지나, 그만큼 메모리나 디스크를 더 차지하므로 필요한 부분에만 text 로 지정해야 합니다.

제대로 매핑된것인지 확인하기 위해 아래처럼 보냅니다.

GET /movie/_mapping

아래처럼 응답이 올겁니다. 세팅한 대로 잘 적용되어 있습니다.

{
  "movie" : {
    "mappings" : {
      "properties" : {
        "genre" : {
          "type" : "keyword"
        },
        "name" : {
          "type" : "text"
        },
        "year" : {
          "type" : "integer"
        }
      }
    }
  }
}

위 json 에서 우린 type 이라는 파라메타만 이용했는데, 아래 링크를 통해 더 다양한 옵션을 확인할 수 있습니다.

https://www.elastic.co/guide/en/elasticsearch/reference/7.4/mapping-params.html

 

Mapping parameters | Elasticsearch Guide [7.4] | Elastic

 

www.elastic.co

이제 index 가 만들어졌으니 데이터를 넣어 보도록 하겠습니다.

아래 2가지를 키바나 에서 실행합니다.

POST /movie/_doc
{
  "name":"game of throne 1",
  "year": 2020,
  "genre": "action"
}
POST /movie/_doc
{
  "name":"game of throne 2",
  "year": 2020,
  "genre": "action"
}

이제 검색을 해봅시다.

아래처럼 name 이라는 필드에 GAME 이라는 게 들어간 걸 검색합니다.

GET /movie/_search
{
  "query": {
    "match": {
      "name": "GAME"
    }
  }
}

그 결과 아래처럼 2개의 다큐먼트가 검색됩니다.

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 0.18232156,
    "hits" : [
      {
        "_index" : "movie",
        "_type" : "_doc",
        "_id" : "NJDqFW4B8s5r-NlInZBo",
        "_score" : 0.18232156,
        "_source" : {
          "name" : "game of throne 1",
          "year" : 2020,
          "genre" : "action"
        }
      },
      {
        "_index" : "movie",
        "_type" : "_doc",
        "_id" : "NZDqFW4B8s5r-NlIzJB3",
        "_score" : 0.18232156,
        "_source" : {
          "name" : "game of throne 2",
          "year" : 2020,
          "genre" : "action"
        }
      }
    ]
  }
}

저는 검색시 아래처럼 match 라는 걸 이용했습니다. 이 외에도 term 등 다양한 파라메타들이 있습니다.

{
  "query": {
    "match": {
      "name": "GAME"
    }
  }
}

더 다양한 옵션들은 아래 링크를 참고해주세요

https://www.elastic.co/guide/en/elasticsearch/reference/7.4/search-request-body.html#request-body-search-query

 

Request Body Search | Elasticsearch Guide [7.4] | Elastic

Highlighters don’t reflect the boolean logic of a query when extracting terms to highlight. Thus, for some complex boolean queries (e.g nested boolean queries, queries using minimum_should_match etc.), parts of documents may be highlighted that don’t c

www.elastic.co

이제 다큐먼트를 삭제 해보겠습니다.

삭제 방법은 다양한데, 아래처럼 검색조건에 해당하는걸 삭제할 수도 있고,

DELETE /movie
{
  "query": {
    "match": {
      "name": "GAME"
    }
  }
}

특정 다큐먼트 id만 삭제할수도 있습니다. 자세한 건 아래 링크를 확인하세요.

https://www.elastic.co/guide/en/elasticsearch/reference/7.4/docs-delete.html

 

Delete API | Elasticsearch Guide [7.4] | Elastic

Removes a JSON document from the specified index. DELETE / /_doc/<_id> You use DELETE to remove a document from an index. You must specify the index name and document ID. Optimistic concurrency controledit Delete operations can be made conditional and only

www.elastic.co

 

 

출처 : https://m.blog.naver.com/PostView.nhn?blogId=semtul79&logNo=221691981178&proxyReferer=https:%2F%2Fwww.google.com%2F 

 

엘라스틱서치 ( elasticsearch ) 인덱스 생성, CRUD , ...

#엘라스틱서치 ( #elasticsearch ) 에 #인덱스 를 생성하고 #매핑 을 설정한 후 실제로 데이터를 insert, d...

blog.naver.com

 

300x250
반응형