Skip to content

Latest commit

 

History

History
328 lines (177 loc) · 11.2 KB

[3주차]4장 엘라스틱서치 검색.md

File metadata and controls

328 lines (177 loc) · 11.2 KB

4장. 엘라스틱서치: 검색

쿼리 컨텍스트와 필터 컨텍스트


쿼리 컨텍스트란?
  • 질의에 대한 유사도를 계산해 이를 기준으로 더 정확한 결과를 먼저 보여준다.

    • 4.3에서 유사도를 계산하는 원리 나온다.
  • 도큐먼트에 원하는 값이 포함되어있는지 연관성을 계산해서 최대한 비슷한 도큐먼트들을 찾아준다.

필터 컨텍스트란?
  • 유사도를 계산하지 않고 일치 여부에 따른 결과만을 반환한다.

  • 정확하게 원하는 값과 일치하는지 예/아니요 결과만 확인하면된다.

  • 스코어 계산을 하지 않는다.

    • 전체적인 쿼리 속도를 올릴 수 있다.

    • 결과에 대한 업데이트를 매번 수행할 필요가 없기 때문에 캐시를 이용할 수 있다. 즉, 캐시를 이용한 빠른 검색을 하려며녀 필터 컨텍스트를 이용해야 한다.

    • 엘라스틱서치는 기본적으로 힙 메모리의 10%를 캐시에 이용한다.

필터 컨텍스트와 쿼리 컨텍스트를 구분하는 특별한 API가 있는 것은 아니며 모두 search API를 사용한다. 단, 필터 컨텍스트는 논리(bool) 쿼리 내부의 filter 타입에 적용된다.

예전 1.x 버전에서는 qeuryfilter처럼 명확히 구분되어 문법상 쿼리와 필터 컨텍스트를 구분할 수 있었다. 하지만 논리 쿼리가 나오면서 필터 컨텍스트는 모두 논리 쿼리에 포함되었다.

현재는 쿼리/필터 컨텍스트를 조합해 사용하는 방향으로 가능 추세이다.

쿼리 스트링과 쿼리 DSL


쿼리 스트링이란?
  • 한 줄 정도의 간단한 쿼리에 사용한다.

  • 복잡해지면 가독성이 떨어질 수 있다.

  • ex)

      GET kibana_sample_data_ecommerce/_search?q=customer_full_name:Mary
쿼리 DSL이란?
  • 한 줄에 넣기 힘든 복잡한 쿼리에 사용한다.

  • Request Body 안에 JSON 형태로 쿼리 작성

  • ex)

    GET kibana_sample_data_ecommerce/_search
    {
        "query": {
            "match": {
                "customer_full_name": "Mary"
            }
        }
    }
  • 익숙해지면 쿼리 스트링보다 쿼리 DSL이 더 편하다고 한다.

유사도 스코어


유사도 스코어란?
  • 질의문과 도큐먼트의 유사도를 표현하는 값

    • 스코어가 높을수록 찾고자 하는 도큐먼트에 가깝다.
  • 기본적으로 BM25 알고리즘을 이용해 유사도 스코어를 계산한다.

    • 검색, 추천에 많이 사용되는 알고리즘

    • 엘라스틱에서 지원하는 다양한 알고리즘 사용 가능

  • 쿼리에 explain 옵션을 추가하면 스코어가 어떤 식으로 계산되었는지 확인 가능하다.

  • TF(Term Frequency)-IDF(Inverse Document Frequency) 알고리즘

    • 5.x 이전 버전에서 사용, 개념에 문서 길이를 고려한 알고리즘

    • 검색어가 문서에서 얼마나 자주 나타나는지, 검색어가 문서 내에서 중요한 용어인지 등을 판단하는 근거를 제공한다.

  • IDF(Inverse Document Frequency)

    • 문서 빈도는 특정 용어가 얼마나 자주 등장했는지를 의미하는 지표

    • to, the, 그리고, 그러나 등과 같은 접속부사는 자주 등장하지만 큰 의미없음.

    • 문서 빈도의 역수는 도큐먼트 내에서 발생 빈도가 적을수록 가중치를 높게 주는 것

    • "idf, computed as log( 1 + ( N - n + 0.5 ) / ( n + 0.5 )) from:"

      • n은 검색했던 용어가 몇 개의 도큐먼트에 있는지

      • N은 인덱스의 전체 도큐먼트 수

  • TF(Term Frequency)

    • 용어 빈도는 특정 용어가 하나의 도큐먼트에 얼마나 많이 등장하는지를 의미하는 지표

    • "tf, computed as freq / ( freq + k1 * ( 1 - b + b * dl / avgdl )) from:"

    • dl이 작고 avgdl이 클수록 TP 값이 크다.

      • freq: 도큐먼트 내에서 용어가 나온 횟수

      • k1, b: 알고리즘을 정규화하기 위한 가중치로, 엘라스틱서치가 디폴트로 취하는 상수

      • dl: 필드 길이

      • avgdl: 전체 도큐먼트에서 평균 필드 길이

쿼리


  • 쿼리는 크게 리프 쿼리와 복합 쿼리로 나뉜다.

  • 리프 쿼리: 특정 필드에서 용어를 찾는 쿼리

    • match, term, range 쿼리 등이 있다.
  • 복합 쿼리: 쿼리를 조합해 사용되는 쿼리

    • bool 등이 있다.
전문 쿼리와 용어 수준 쿼리
  • 전문 쿼리: 전문 검색을 위해 사용되는 쿼리

    • 인덱스 매핑 시 텍스트 타입으로 매핑해야 한다.

      • 분석기에 의해 토큰으로 분리된다.
    • 구글, 네이버에서 검색어를 이용해 검색하는 방식과 같다

    • match query, match phrase query, multi-match query, query string query 등

  • 용어 수준 쿼리: 정확히 일치하는 용어를 찾기 위해 사용되는 쿼리

    • 인덱스 매핑 시 필드를 키워드 타입으로 매핑해야 한다.

      • 인덱싱 과정에서 분석기를 사용하지 않는다.

      • 분석되지 않은 검색어와 도큐먼트 용어를 그대로 매칭한다.

    • 숫자, 날짜, 범주형 데이터를 정확하게 검색할 때 사용되며 RDB의 WHERE 절과 비슷하다.

    • term query, terms query, fuzzy query 등

자주 사용되는 쿼리들
  • 매치 쿼리(전문 쿼리의 가장 기본)

    • 특정 용어나 용어들을 검색할 때 사용(= 검색하고 싶은 필드를 알아야 한다.)

    • 용어들 간의 공백은 OR로 인식

    • operator라는 파라미터를 "and"로 지정해주면 and 조건으로 검색된다.

    • 텍스트 타입으로 매핑된 필드를 대상으로 전문 검색에 사용해야 한다.

  • 매치 프레이즈 쿼리

    • 구(phrase)를 검색할 때 사용

      • phrase: 동사가 아닌 2개 이상의 단어가 연결되어 만들어지는 단어

      • ex) 빨간색 바지, 65인치 텔레비전

    • 단어의 순서 중요하고 검색 또한 용어의 순서까지 일치해야 맞다.

    • 많은 리소스를 요구하기 때문에 자주 사용하는 것은 좋지 않다.

  • 용어 쿼리(용어 수준 쿼리의 대표적인 쿼리)

    • 검색어가 분석기에 의해 토큰화되지 않는다.

    • 대소문자와 용어의 순서까지 정확하게 일치해야한다

    • 키워드 타입으로 매핑된 필드를 대상으로 주로 키워드 검색이나 범주형 데이터를 검색하는 용도로 사용하자

  • 용어들 쿼리

    • 여러 용어들을 검색해준다.

    • 키워드 타입 매핑된 필드 대상

    • 대소문자 및 용어 순서 정확하게 일치해야함

  • 멀티 매치 쿼리

    • 어떤 필드에 용어또는 구절이 속해있는지 모를 때 사용

    • 여러 개의 필드에서 검색하기 위한 전문 검색 쿼리의 일종

    • 텍스트 타입으로 매핑된 필드에서 사용하는 것이 좋다.

    • 필드명에 * 같은 와일드카드를 사용해 이름이 유사한 복수의 필드를 선택할 수 있다.

  • 필드에 가중치 두기

    • 부스팅 기법: 여러 개의 필드 중 특정 필드에 가중치를 두는 방법, 멀티 매치 쿼리에서 주로 사용

      • ex) 제목에 용어가 있을지 본문에 용어가 있을지 모를 때 제목이 일반적으로 더 중요하니까 제목 필드에 가중치를 준다.
  • 범위 쿼리

    • 특정 날짜/숫자/IP 타입의 범위 안에 포함된 데이터들을 검색할 때 사용

    • 문자형, 키워드 타입의 데이터에 사용 불가

    • 검색 범위를 지정하는 파라미터를 지정 할 수 있다. (부등호는 지원되지 않는건가?)

      • gte(같거나 큰 값), gt(큰 값), lte(같거나 작은 값), lt(작은 값)
    • now 표현식을 이용해서 현재 시간을 기준으로 검색 가능

    • 범위 데이터 타입

      • integer_range, float_range, long_range, double_range, date_range, ip_range
    • relation 파라미터(세 가지 값)

      • intersects(기본값): 쿼리 범위 값이 도큐먼트의 범위 데이터를 일부라도 포함

      • contains: 도큐먼트가 쿼리 범위 값을 모두 포함

      • within: 도큐먼트 범위 데이터가 쿼리 범위 값 내에 전부 속해야 함

      • 문서 숫자 범위
        1 10 ~ 19
        2 20 ~ 29
        3 30 ~ 39
        4 40 ~ 49
        쿼리 범위 값 relation 찾은 문서
        15 ~ 45 intersects 1,2,3,4
        15 ~ 45 within 2,3
        25 ~ 29 contains 2
        25 ~ 35 contains x
  • 논리 쿼리(= 복합 쿼리)

    • 쿼리끼리 조합 가능하다.

    • 4개의 타입 지원

      • must

        • 쿼리를 실행하여 인 도큐먼트를 찾는다.

        • 복수의 쿼리를 실행하면 AND 연산을 한다.

      • must_not

        • 쿼리를 실행하여 거짓인 도큐먼트를 찾는다.

        • 다른 타입과 같이 사용할 경우 도큐먼트에서 제외한다.

      • should

        • 단독으로 사용 시 쿼리를 실행하여 인 도큐먼트를 찾는다.

        • 복수의 쿼리를 실행하면 OR 연산을 한다.

        • 다른 타입과 같이 사용할 경우 스코어에만 활용된다.

        • 도큐먼트의 검색 순위를 최적화할 수 있다.

      • filter

        • 쿼리를 실행하여 '예/아니요' 형식의 필터 컨텍스트를 수행한다.

        • 스코어 검색을 하지 않기 때문에 검색 성능을 높일 수 있다.

  • 패턴 검색

    • 대략적인 키워드나 몇 개의 알파벳만 알고 있다면 패턴을 이용해 검색할 수 있다.

    • 와일드카드 쿼리

      • 검색어 앞에는 사용하지 말자(속도가 매우 느려진다)

      • *: 공백까지 포함하여 글자 수 상관없이 모든 문자 매칭 가능

      • ?: 오직 한 문자만 매칭 가능. 문자 길이 중요

    • 정규식 쿼리

      • 정규 표현식에서 +, ?, * 같은 기호는 맨 앞에 올 수 없다.

      • .: 하나의 문자를 의미하고 어떤 문자가 와도 상관없이 매칭되었다고 판단.문자 길이 중요

      • +: +기호 앞 문자와 같은 문자가 한 번 이상 반복되면 매칭되었다고 판단.

      • *: *기호 앞 문자와 같은 문자가 0번, 혹은 여러번 반복되면 매칭되었다고 판단.

      • ?: ?기호 앞 문자와 같은 문자가 0번, 혹은 한 번 나타나면 매칭되었다고 판단.

      • (): ()기호는 문자를 그룹핑하여 반복되는 문자들을 매핑시킨다. 다른 기호들과 혼합하여 사용된다.

      • []: []기호는 문자를 클래스화하여 특정 범위의 문자들을 매칭한다.

        • EX) [ab]는 a나 b가 오면 매칭 [a-z]는 a와 z 사이의 문자가 오면 매칭 [^k]는 k가 아닌 다른 문자가 오면 매칭