ElasticSearch 개념 1탄. Elasticsearch 검색엔진 및 쿼리

5 분 소요

Elasticsearch 개념(1)

도큐먼트(document)와 인덱스(Index)?

  • Elasticsearch 에서는 단일 데이터 단위를 도큐먼트(document) 라고 하며 이 도큐먼트를 모아놓은 집합을 인덱스(Index) 라고 합니다.

데이터 본문 검색은 어떻게?

  • 가장 쉽고 많이 사용되는 것은 match 쿼리입니다.
  • 데이터 본문 검색으로 field 필드값이 value 인 도큐먼트를 검색하기 위해서는 다음 명령을 실행합니다.
  • 데이터 본문(data body) 검색은 검색 쿼리를 데이터 본문으로 입력하는 방식입니다.

elasticsearch 입력 방식은?

  • 쿼리 입력은 항상 query 지정자로 시작합니다. 그 다음 레벨에서 쿼리의 종류를 지정하는데 아래에서는 match 쿼리를 지정했습니다.
    GET test/_search
    {
    "query": {
      "match": {
        "field": "value"
      }
    }
    }
    

멀티테넌시(Multitenancy) 왜 쓰는가?

  • 여러 개의 인덱스를 한꺼번에 묶어서 검색할 수 있기 때문입니다.
  • 예를 들어, logs-2018-01, logs-2018-02 … 와 같이 날짜별로 저장된 인덱스들이 있다면 이 인덱스들을 모두 logs-*/_search 명령으로 한꺼번에 검색이 가능합니다.

Elasticsearch의 장점은? 장점 1: Elasticsearch는 사용자가 이런 여러가지 검색 조건들에 대해 목표로 하는 검색 기능을 구현할 수 있도록 다양한 기능들을 제공합니다. Elasticsearch는 데이터를 실제로 검색에 사용되는 검색어인 텀(Term) 으로 분석 과정을 거쳐 저장하기 때문에 검색 시 대소문자, 단수나 복수, 원형 여부와 상관 없이 검색이 가능합니다. 이러한 Elasticsearch의 특징을 풀 텍스트 검색(Full Text Search) 이라고 하며 한국어로 전문 검색 이라고도 합니다.

장점 2: Elasticsearch 는 검색을 위한 쿼리 기능을 제공합니다.

  • 이런 데이터 시스템에서 제공하는 쿼리 기능을 Query DSL (Domain Specific Language) 이라고 합니다.
  • Elasticsearch 의 Query DSL 은 모두 json 형식으로 입력해야 합니다.

Elastcisearch 검색에 사용되는 주요 쿼리들을 어떤 것들이 있는가? 1) mathch_all

  • match_all 은 별다른 조건 없이 해당 인덱스의 모든 도큐먼트를 검색하는 쿼리입니다.
  • 검색 시 쿼리를 넣지 않으면 elasticsearch는 자동으로 match_all을 적용해서 해당 인덱스의 모든 도큐먼트를 검색합니다.

2) match

  • match 쿼리는 풀 텍스트 검색에 사용되는 가장 일반적인 쿼리입니다. 예시1) 다음은 match 쿼리를 이용하여 my_index 인덱스의 message 필드에 dog 가 포함되어 있는 모든 문서를 검색합니다.
  • match 검색에 여러 개의 검색어를 집어넣게 되면 디폴트로 OR 조건으로 검색이 되어 입력된 검색어 별로 하나라도 포함된 모든 문서를 모두 검색합니다.
  • 검색어가 여럿일 때 검색 조건을 OR 가 아닌 AND 로 바꾸려면 operator 옵션을 사용할 수 있습니다.
    GET my_index/_search
    {
    "query": {
      "match": {
        "message": {
          "query": "quick dog",
          "operator": "and"
        }
      }
    }
    }
    

“quick dog” 라는 구문을 공백을 포함해 정확히 일치하는 내용을 검색하는 방법은?

  • match_phrase 쿼리를 사용하면 됩니다.
  • match_phrase 쿼리는 입력된 검색어를 순서까지 고려하여 검색을 수행합니다.
  • match_phrase 쿼리는 slop 이라는 옵션을 이용하여 slop에 지정된 값 만큼 단어 사이에 다른 검색어가 끼어드는 것을 허용할 수 있습니다.
  • slop을 너무 크게 하면 검색 범위가 넓어져 관련이 없는 결과가 나타날 확률도 높아지기 때문에 1 이상은 사용하지 않는 것을 권장 드립니다.
    GET my_index/_search
    {
    "query": {
      "match_phrase": {
        "message": {
          "query": "lazy dog",
          "slop": 1
        }
      }
    }
    }
    

query_string을 왜 쓰는 것인가? 루씬의 검색 문법을 본문 검색에 이용하고 싶을 때 query_string 쿼리을 사용합니다. 예시1) message 필드에서 lazy와 jumping을 모두 포함하거나 또는 “quick dog” 구문을 포함하는 도큐먼트를 검색하는 쿼리입니다. match_phrase 처럼 구문 검색을 할 때는 검색할 구문을 쌍따옴표 " 안에 넣습니다.

GET my_index/_search
{
  "query": {
    "query_string": {
      "default_field": "message",
      "query": "(jumping AND lazy) OR \"quick dog\""
    }
  }
}

Bool 복합 쿼리(Bool Query) 왜 쓰는 것인가? query_string 쿼리는 여러 조건을 조합하기에는 용이한 문법이지만 옵션이 한정되어 있습니다.

어떤 한정,한계가 있는 것인가? 본문 검색에서 여러 쿼리를 조합하기 위해서는 상위에 bool 쿼리를 사용하고 그 안에 다른 쿼리들을 넣는 식으로 사용이 가능합니다. bool 쿼리는 다음의 4개의 인자를 가지고 있으며 그 인자 안에 다른 쿼리들을 배열로 넣는 방식으로 동작합니다.

  • must : 쿼리가 참인 도큐먼트들을 검색합니다.
  • must_not : 쿼리가 거짓인 도큐먼트들을 검색합니다.
  • should : 검색 결과 중 이 쿼리에 해당하는 도큐먼트의 점수를 높입니다.
  • filter : 쿼리가 참인 도큐먼트를 검색하지만 스코어를 계산하지 않습니다. must 보다 검색 속도가 빠르고 캐싱이 가능합니다. 다음은 단어 “quick”과 구문 “lazy dog”가 포함된 모든 문서를 검색하는 쿼리입니다.
    GET my_index/_search
    {
    "query": {
      "bool": {
        "must": [
          {
            "match": {
              "message": "quick"
            }
          },
          {
            "match_phrase": {
              "message": "lazy dog"
            }
          }
        ]
      }
    }
    }
    

    bool query의 장점

  • bool 쿼리를 이용해서 복합적인 검색 기능을 구현할 수 있습니다.

표준 SQL의 AND, OR 조건과 Elasticsearch의 must, must_not, should의 차이점은?

  • 표준 SQL의 AND, OR 조건 들은 2개의 조건값에 대한 이항 연산자 입니다.
  • Elasticsearch의 must, must_not, should 등은 내부에 있는 각각의 쿼리들에 대해 이 쿼리는 참 또는 거짓으로 적용하는 단항 연산자라고 생각을 하면 조금 더 이해하기 쉽습니다.

정확도(Relevancy)는 왜 필요한지? 각 쿼리 결과들이 얼마나 정확한지에 대한 판단은 보통 불가능합니다 정확도(Relevancy)의 장점은? 이 정확도를 기반으로 사용자가 가장 원하는 결과를 먼저 보여줄 수 있습니다.

스코어 (score) 점수 왜 필요한지? Elasticsearch의 검색 결과에는 스코어 점수가 표시가 됩니다. 이 점수는 검색된 결과가 얼마나 검색 조건과 일치하는지를 나타내며 점수가 높은 순으로 결과를 보여줍니다.

bool 쿼리의 should의 쓰임은? 검색 점수를 조정하기 위해 사용할 수 있습니다. 예시1) lazy 가 포함된 결과에 가중치를 줘서 상위로 올리고 싶으면 다음과 같이 should 안에 lazy 를 찾는 검색을 추가합니다.

GET my_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "message": "fox"
          }
        }
      ],
      "should": [
        {
          "match": {
            "message": "lazy"
          }
        }
      ]
    }
  }
}

Elasticsearch 풀 텍스트 검색의 장점은? 장점 1: 풀 텍스트 검색은 스코어 점수 기반으로 정확도(relevancy)가 높은 결과부터 가져옵니다. 장점 2: 검색 조건의 참 / 거짓 여부만 판별해서 결과를 가져오는 것이 가능합니다. 이 특성을 정확값(Exact Value) 이라고 하는데 말 그대로 값이 정확히 일치 하는지의 여부 만을 따지는 검색입니다.

filter를 왜 쓰는 것인지? filter는 검색에 조건은 추가하지만 스코어에는 영향을 주지 않도록 제어할 때 사용합니다. 예시1) 보통 쇼핑몰에서 검색어로 정확도가 높은 상품명을 검색하면서 생산 업체를 다시 필터링 하는 등의 용도로 사용이 가능합니다.?

keyword의 쓰임은? 문자열 데이터는 keyword 형식으로 저장하여 정확값 검색이 가능합니다. keyword 타입으로 저장된 필드는 스코어를 계산하지 않고 정확값의 일치 여부만을 따지는데 사용됩니다

Elasticsearch에서 날짜나 숫자형식을 저장하려면 어떻게?

  • Elasticsearch는 숫자나 날짜 형식들의 저장이 가능합니다.
  • 숫자, 날짜 형식은 range 쿼리를 이용해서 검색을 합니다. 시간?
  • range 쿼리는 range : { <필드명>: { <파라메터>:<값> } } 으로 입력됩니다.
  • range 쿼리 파라메터는 아래의 4가지가 있습니다. gte (Greater-than or equal to) - 이상 (같거나 큼) gt (Greater-than) – 초과 (큼) lte (Less-than or equal to) - 이하 (같거나 작음) lt (Less-than) - 미만 (작음)

날짜? Elasticsearch 에서 날짜 값은 2016-01-01 또는 2016-01-01T10:15:30 과 같이 JSON 에서 일반적으로 사용되는 ISO8601 형식을 사용합니다. 쿼리의 날짜 포맷을 다르게 하고 싶으면 format 옵션의 사용이 가능합니다.

GET phones/_search
{
  "query": {
    "range": {
      "date": {
        "gt": "31/12/2015",
        "lt": "2018",
        "format": "dd/MM/yyyy||yyyy"
      }
    }
  }
}

날짜를 검색 할 때는 검색하는 현재 시간을 가져오는 예약어 now와 y(년), M(월), d(일), h(시), m(분), s(초), w(주) 등의 사용이 가능합니다. 다음은 date의 값이 2016년 1월 1일에서 6개월 후인 날 부터 오늘보다 365일 전인 날 사이의 데이터를 가져오는 쿼리입니다. 지금까지 살펴본 range 쿼리의 스코어는 모두 “_score” : 1.0로 동일합니다. range 쿼리는 기본적으로 정확도를 계산하지 않습니다. 필드의 값이 1000 보다 같거나 작은지 아닌지의 true / false 여부만을 판단합니다. 이번 장에서 살펴본 쿼리 외에도 geo_point 나 nested 같은 특수한 데이터들을 검색하는 쿼리들도 있습니다.

[참고자료] Elastic 가이드북 https://git-scm.com/book/ko/v2/Git-%EB%8F%84%EA%B5%AC-%EC%84%9C%EB%B8%8C%EB%AA%A8%EB%93%88

카테고리:

업데이트:

댓글남기기