기초부터 다지는 ElasticSearch 운영 노하우 1-2장을 읽고 요약하였습니다.
1. Elasticsearch 소개 및 특징
Elasticsearch란
Elasticsearch 는 루씬 기반의 오픈소스 검색엔진이다. JSON 기반의 문서를 저장하고 검색할 수 있으며 문서들의 데이터를 기반으로 분석 작업이 가능하다.
특징
| 특징 | 설명 | 
| 준실시간성 | 실시간이라고 생각할 만큼 색인된 데이터가 매우 빠르게 검색됨 (실시간은 아님) | 
| 클러스터 구성 | 한 대 이상의 노드를 클러스터로 구성하여 안정성을 보장하고 부하 분산이 가능 | 
| 스키마리스(schemaless) | 입력된 데이터에 대해 미리 정의하지 않아도 동적으로 스키마 생성 가능 | 
| Rest API | SQL이 아닌 Rest API 기반의 쉬운 인터페이스를 제공하여 비교적 진입장벽이 낮음 | 
2. Elasticsearch의 기본동작
실행하기
# docker를 활용하여 실행
> docker run -p 9200:9200 -p 9300:9300 -d --name elasticsearch -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.13.3
# Hello, Elasticsearch
> curl localhost:9200 
{
  "name" : "f244322eb8b9", # 노드 이름
  "cluster_name" : "docker-cluster", # 클러스터 이름
  "cluster_uuid" : "yVpdbMETSI29DOBWO6im0w", # 클러스터 uuid
  "version" : {
    "number" : "7.13.3", # 노드의 Elasticsearch 버전
    "build_flavor" : "default",
    "build_type" : "docker", # 설치 형태
    "build_hash" : "5d21bea28db1e89ecc1f66311ebdec9dc3aa7d64",
    "build_date" : "2021-07-02T12:06:10.804015202Z",
    "build_snapshot" : false,
    "lucene_version" : "8.8.2",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}
Bash
복사
문서 색인/조회/삭제/수정
•
검색엔진에서 색인이란 검색을 빠르게 하기 위해 데이터를 저장하는 행위를 말한다.
•
Elasticsearch의 색인 과정
◦
Elasticsearch에서의 색인은 인덱스 생성, 타입 생성, 스키마 생성을 동반한다.
•
문서의 색인과 조회 (id 지정시)
# id=1로 지정하여 색인(PUT)
> curl -XPUT "http://localhost:9200/books/_doc/1" -H 'Content-Type: application/json' -d '{
  "title" : "Elasticsearch Guide",
  "author" : "Kim",
  "date" : "2014-05-01",
  "pages" : 250
}'# id=1로 색인된 문서가 결과로 출력
# 조회
> curl -XGET http://localhost:9200/books/_doc/1
Bash
복사
•
문서의 색인과 조회 (id 미지정시)
# id 지정없이 색인(POST)
> curl -XPOST "http://localhost:9200/books/_doc" -H 'Content-Type: application/json' -d '{
  "title" : "Elasticsearch Guide ",
  "author" : "Kim",
  "date" : "2014-05-01",
  "pages" : 250
}'# ${생성된ID}와 함께 색인된 문서가 결과로 출력
# 조회 
> curl -XGET http://localhost:9200/books/_doc/${생성된ID}
Bash
복사
•
문서 삭제
> curl -XDELETE "http://localhost:9200/books/_doc/1
# 삭제 결과 출력
# 삭제된 문서를 조회할 경우 found=false 결과가 나옴
Bash
복사
•
인덱스 생성 및 조회
# contents 인덱스 생성
> curl -XPUT "http://localhost:9200/contents"# 모든 인덱스 목록 및 확인
> curl -XGET "http://localhost:9200/_cat/indices/contents"
health status index    uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   books    fUYfNR_TSiaTF7uvntj7lw   1   1          1           10     12.4kb         12.4kb
yellow open   contents YuRJSf7qRAee9o1hYdgtoA   1   1          0            0       208b           208b
Bash
복사
•
스키마 확인 (인덱스의 필드와 타입 확인)
# books 인덱스의 스키마 확인
> curl -XGET "http://localhost:9200/books/_mappings?pretty"
{
  "books" : {
    "mappings" : {
      "properties" : {
        "author" : { # author 필드
          "type" : "text", # 타입: 문자열
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "date" : { # date 필드
          "type" : "date" # 타입: 날짜
        },
        "pages" : { # pages 필드
          "type" : "long" # 타입: long
        },
        "title" : { # title 필드
          "type" : "text", # 타입: 문자열
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}
Bash
복사
•
문서 수정
◦
색인 후에 동일한 id로 다시 색인할 경우 문서내용의 변경과 함께 _version은 증가하고 result는 updated로 변경됨
◦
스키마가 정의되어 있다하더라도 새로운 필드가 추가되면 해당 필드가 색인되고 스키마도 추가로 정의된다.
◦
기존의 필드와 충돌하는 타입으로 새로운 문서가 인입될 경우 스키마 충돌 에러가 발생하고 색인이 실패한다.
문서 검색하기
•
색인한 문서는 다음과 같이 검색이 가능하다.
•
curl -XPOST localhost:9200/_bulk -H 'Content-Type: application/json' -d '{ "index" : { "_index" : "books", "_type" : "_doc", "_id" : "1" } }
{ "title" : "Elasticsearch Guide", "author" : "Kim", "pages" : 250 }
{ "index" : { "_index" : "books", "_type" : "_doc", "_id" : "2" } }
{ "title" : "Elasticsearch Easy Guide", "author" : "Lee", "pages" : 300 }
{ "index" : { "_index" : "books", "_type" : "_doc", "_id" : "3" } }
{ "title" : "Elasticsearch Advanced Guide", "author" : "Park", "pages" : 400 }
'
Bash
복사
•
풀스캔 검색: 모든 데이터를 검색
> curl -XGET "http://localhost:9200/books/_search?q=*"# 모든 문서 출력
{"took":43,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":3,"relation":"eq"},"max_score":1.0,"hits":[{"_index":"books","_type":"_doc","_id":"1","_score":1.0,"_source":{ "title" : "Elasticsearch Guide", "author" : "Kim", "pages" : 250 }},{"_index":"books","_type":"_doc","_id":"2","_score":1.0,"_source":{ "title" : "Elasticsearch Easy Guide", "author" : "Lee", "pages" : 300 }},{"_index":"books","_type":"_doc","_id":"3","_score":1.0,"_source":{ "title" : "Elasticsearch Advanced Guide", "author" : "Park", "pages" : 400 }}]}}
Bash
복사
•
문자열 검색: 특정 문자열이 포함된 문서 찾기
> curl -XGET "http://localhost:9200/books/_search?q=Lee"# Lee 문자열이 포함된 문서 출력
{"took":6,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":1,"relation":"eq"},"max_score":0.9808291,"hits":[{"_index":"books","_type":"_doc","_id":"2","_score":0.9808291,"_source":{ "title" : "Elasticsearch Easy Guide", "author" : "Lee", "pages" : 300 }}]}}
Bash
복사
•
match 검색: 특정 필드의 값이 조건과 일치하는 문서 찾기
> curl -XGET "http://localhost:9200/books/_search?" -H 'Content-Type: application/json' -d '{
  "query": {
    "match": {
      "pages": 250
    }
  }
}
'
# pages=250인 문서만 출력
{"took":1,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":1,"relation":"eq"},"max_score":1.0,"hits":[{"_index":"books","_type":"_doc","_id":"1","_score":1.0,"_source":{ "title" : "Elasticsearch Guide", "author" : "Kim", "pages" : 250 }}]}}
Bash
복사
•
범위 검색: 특정 필드 값의 범위를 지정하여 문서 검색
> curl -XGET "http://localhost:9200/books/_search?" -H 'Content-Type: application/json' -d '{
  "query": {
    "bool": {
      "must": { "match_all": {} },
      "filter": {
        "range": {
          "pages": {
            "gt": 250
          }
        }
      }
    }
  }
}
'
# pages>250인 문서만 출력
{"took":79,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":2,"relation":"eq"},"max_score":1.0,"hits":[{"_index":"books","_type":"_doc","_id":"2","_score":1.0,"_source":{ "title" : "Elasticsearch Easy Guide", "author" : "Lee", "pages" : 300 }},{"_index":"books","_type":"_doc","_id":"3","_score":1.0,"_source":{ "title" : "Elasticsearch Advanced Guide", "author" : "Park", "pages" : 400 }}]}}
Bash
복사
•
구체적인 검색조건의 차이는 다른 글에서 다룰 예정이다.
문서 분석하기
•
Elasticsearch에서는 색인된 문서를 바탕으로 분석(aggregation)이 가능하다.
•
위의 books 데이터를 활용한다.
•
빈도 세기
# size=0을 조건으로 넣어서 분석결과만 출력하고 검색결과는 생략한다.
> curl -XGET "http://localhost:9200/books/_search?pretty" -H 'Content-Type: application/json' -d '{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "author.keyword"
      }
    }
  }
}
'
# author(저자) 필드를 기반으로 빈도 출력
{
  # ... 
  "aggregations" : {
    "group_by_state" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "Elasticsearch Advanced Guide",
          "doc_count" : 1
        },
        {
          "key" : "Elasticsearch Easy Guide",
          "doc_count" : 1
        },
        {
          "key" : "Elasticsearch Guide",
          "doc_count" : 1
        }
      ]
    }
  }
}
Bash
복사
•
평균 내기
# size=0을 조건으로 넣어서 분석결과만 출력하고 검색결과는 생략한다.
> curl -XGET "http://localhost:9200/books/_search?pretty" -H 'Content-Type: application/json' -d '{
  "size": 0,
  "aggs": {
    "avg_pages": {
      "avg": {
        "field": "pages"
      }
    }
  }
}
'
# pages의 평균값 출력
{
  # ...
  "aggregations" : {
    "avg_pages" : {
      "value" : 316.6666666666667
    }
  }
}
Bash
복사

