ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 11. Query DSL 구조 및 파라미터
    BackEnd/elasticsearch 2021. 10. 2. 15:05
    반응형

      엘라스틱서치로 검색 질의를 요청할 때는 Request Body 검색과 URI 검색 모두 _search API를 이용해 검색을 질의합니다. 하지만 Query DSL(JSON 구조 기반)을 이용하면 여러 개의 질의를 조합하거나 질의 결과에 대해 다시 검색을 수행하는 등 기존의 URI 검색보다 강력한 검색이 가능해집니다.

     

    1. Query DSL 쿼리의 구조

    # 요청 JSON 구조
    {
    	"size":       # 리턴받는 결과의 개수 (기본값 : 10)
    	"from":       # 몇 번째 문서부터 가져올지 지정 (기본값 : 0)
    	"timeout":    # 검색을 요청해서 결과를 받는 데까지 걸리는 시간
                        너무 짧게 잡으면 전체 샤드에서 timeout을 넘기지 않은 문서만 결과로 출력하기에
                        상황에 따라 결과의 일부만 나올 수 있음 (기본값 : 무한대)
    
    	"_source": {} # 검색 시 필요한 필드만 출력하고 싶을 때 사용
    	"query": {}   # 검색 조건문이 들어가야 하는 공간
    	"aggs": {}    # 통계 및 집계 데이터를 사용할 때 사용하는 공간
    	"sort": {}    # 문서 결과를 어떻게 출력할지에 대한 조건을 사용하는 공간
    }
    # 응답 JSON 구조
    {
      "took":         # 쿼리 실행 시간
      "timed_out":    # 쿼리 시간이 초과할 경우를 나타냄
      
      "_shards" : {   
        "total":      # 쿼리를 요청한 전체 샤드의 개수
        "successful": # 성공적으로 응답한 샤드의 개수
        "failed":     # 실패한 샤드의 개수
      },
      
      "hits": {       
        "total":      # 검색어에 매칭된 문서의 전체 개수
        "max_score":  # 일치하는 문서의 스코어 값 중 가장 높은 값
        "hits": []    # 각 문서 정보와 스코어 값
      }
    }

     

    2. Query DSL 쿼리와 필터

      쿼리 컨텍스트 필터 컨텍스트
    용도 전문 검색 시 사용 조건 검색 시 사용(예: Yes/No)
    특징 분석기에 의해 분석이 수행됨.
    연관성 관련 Score 계산.
    루씬 레벨에서 분석 과정을 거처야 하므로 상대적으로 느림.
    Yes/No로 단순 판별 가능
    연관성 관련 계산을 하지 않음.
    엘라스틱서치 레벨에서 처리가 가능하므로 상대적으로 빠름.
    사용 예 "Harry Potter" 같은 문장 분석 "create_year" 필드의 값이 2018년인지 여부
    "status" 필드에 'use'라는 코드 포함 여부
    # 쿼리 컨텍스트
    POST  movie_search/_search
    {
      "query": {
        "match": {
          "movieNm": "기묘한 가족"
        }
      }
    }
    
    # 필터 컨텍스트
    POST movie_search/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match_all": {}
            }
          ],
          "filter": {
            "term": {
              "repGenreNm": "다큐멘터리"
            }
          }
        }
      }
    }

     

    3. Query DSL 주요 파라미터

    1) Multi Index 검색

    POST movie_search,movie_auto/_search # ","를 이용해 다수의 인덱스명 입력
    {
      ...
    }
    
    POST /log-2021-*/_search # 검색 요청 시 인덱스 이름을 지정할 때 "*" 와일드카드 사용
    {
      ...
    }

    2) 쿼리 결과 페이징

    # 첫 번째 페이지 요청
    POST movie_search/_search
    {
       "from": 0,
       "size": 5,
       "query": {
         "term": {
         "repNationNm": "한국"
         }
       }
     }
     
     # 두 번째 페이지 요청
    POST movie_search/_search
    {
       "from": 5,
       "size": 5,
       "query": {
         "term": {
         "repNationNm": "한국"
         }
       }
     }

      엘라스틱서치는 설정된 페이지를 제공하기 위해 전체를 읽어 사이즈만큼 필터링해서 제공하는 구조이기 때문에 페이지 번호가 높아질수록 쿼리 비용은 덩달아 높아질 수밖에 없다는 점에 주의해야 합니다.

     

    3) 쿼리 결과 정렬

    POST movie_search/_search
    {
       "query": {
         "term": {
           "repNationNm" : "한국"
         }
       },
       "sort" :{
         "prdtYear": {
            "order": "asc"
          },
         "_score": {
            "order": "desc"
          }
       }
    }

    4) _source 필드 필터링

    # _source에 검색 결과에 포함하고 싶은 필드 지정
    POST movie_search/_search
    {
       "_source": [
         "movieNm"
       ],
       "query": {
         "term": {
           "repNationNm" : "한국"
         }
       }
    }

    5) 범위 검색

    # lt : <
    # gt : >
    # lte : <=
    # gte : >=
    POST movie_search/_search
    {
      "query": {
        "range": {
          "prdtYear": {
            "gte": "2016",
            "lte": "2017"
          }
        }
      }
    }

    6) operator 설정

      명시적으로 "and"나 "or" 연산자를 지정합니다. operator 파라미터가 생략된 경우에는 기본적으로 텀과 텀에 OR 연산을 적용합니다.

    POST movie_search/_search
    {
      "query": {
        "match": {
          "movieNm": {
            "query": "자전차왕 엄복동",
            "operator": "and" # 생략 시 "자전차왕" or "엄복동" 들어있는 모든 문서 검색
          }
        }
      }
    }

    7) minimum_should_match

      텀의 개수가 몇 개 이상 매칭될 때만 검색 결과로 나오게 할 경우에 사용합니다. 아래 예는 텀의 개수와 minimum_should_match 개수가 일치하기에 AND 연산과 동일한 효과를 낼 수 있습니다.

    POST movie_search/_search
    {
      "query": {
        "match": {
          "movieNm": {
            "query": "자전차왕 엄복동",
            "minimum_should_match": 2
          }
        }
      }
    }

    8) fuzziness

      단순히 같은 값을 찾는 Match Query를 유사한 값을 찾는 Fuzzy Query로 변경할 수 있습니다. 이는 레벤슈타인(Levenshtein) 편집 거리 알고리즘을 기반으로 문서의 필드 값을 여러 번 변경하는 방식으로 동작합니다.

      예를 들어, 편집 거리의 수를 2로 설정한다면 오차범위가 두 글자 이하인 검색 결과까지 포함해서 결과로 출력합니다. 오차범위 값으로 0, 1, 2, AUTO로 총 4자기 값을 사용할 수 있는데, 이는 알파벳에는 유용하지만 한국어에는 적용하기 어렵습니다.

    POST movie_search/_search
    {
      "query": {
        "match": {
          "movieNmEn": {
            "query": "Fli High", # "Fly High" 검색 가능
            "fuzziness": 1
          }
        }
      }
    }

    9) boost

      관련성이 높은 필드나 키워드에 가중치를 더 줄 수 있게 해줍니다. 아래 예는 한글 영화 제목이 일치하면 한글 영화 제목에서 계산되는 스코어에 가중치 값으로 3을 곱합니다.

    POST movie_search/_search
    {
      "query" : {
        "multi_match": {
          "query": "Fly",
          "fields": ["movieNm^3","movieNmEn"]
        }
      }
    }

     

    반응형

    'BackEnd > elasticsearch' 카테고리의 다른 글

    13. 집계(Aggregation)  (0) 2021.10.06
    12. Query DSL의 주요 쿼리  (0) 2021.10.02
    10. 검색 API  (0) 2021.09.25
    09. 문서관리 API(Document API)  (0) 2021.09.24
    08. 엘라스틱서치 분석기  (0) 2021.09.24

    댓글

Designed by Tistory.