Search API

  • 검색을 할 때 사용하는 API
  • 검색은 인덱스 단위로 이루어짐

Request Body 검색

  • Body에 검색할 field와 검색어를 Json형태로 전달하는 방식
  • Query DSL이라는 특별한 문법을 사용
  • Query DSL에서 자세하게 다룰 예정

URI 검색

  • Request Body 검색에 비해 사용하기 편리하지만, 복잡한 쿼리를 사용하기엔 어려움
  POST jake-one/_search?q=the
  POST jake-one/_search?q=field:the
  • field:검색어 형태로 입력이 가능함

  • AND 조건 OR 조건 사용 가능

  POST jake-one/_search?q=one OR third

Multitenancy

  • 여러 개 인덱스를 한번에 묶어서 검색하는 것

  • 날짜별로 지정된 인덱스가 있다면 *를 사용해 묶어서 검색이 가능함

 GET logs-2023-*/_search

QueryDSL

  • 보다 강력한 검색을 위한 도구

  • 정밀한 검색을 위해 Json 구조를 기반으로한 QueryDSL(Domain Specific Language) 사용

  • Query에 사용되는 부분

 {
     "size" : # 반환받는 Document 개수의 값
     ,"from" : # 몇번째 문서부터 가져올지 지정. 기본값은 0
     ,"timeout" : # 검색 요청시 결과를 받는 데까지 걸리는 시간이다. 
     # timeout을 작게하면 전체 샤드에서 timeout을 넘기지 않은 문서만 결과로 출력됨
     # 기본 값은 제한없음
     ,"_source" : # 검색 시 필요한 필드만 출력하고 싶을 때 사용
     ,"query" : # 검색 조건문을 설정할 때 사용
     ,"aggs" : # 통계 및 집계 데이터를 설정할 때 사용
     ,"sort" : # 문서 결과의 정렬 조건을 설정할 때 사용
 }
  • Query 결과에 대한 부분

    {
        "took" : # Query를 실행하는데 걸린 시간
        ,"timed_out" : # Query timeout이 초과했는 지 True, False로 나타낸다
        ,"_shards" : {
            "total" : # Query를 요청한 전체 샤드 개수
            ,"successful" : # Query에 성공적으로 응답한 샤드 개수
            ,"failed" : # Query에 실패한 샤드 개수
        }
        ,"hits" : {
            "total" : # Query에 매칭된 문서의 전체 개수
            ,"max_score" : # Query에 일치하는 문서의 스코어 값중 가장 높은 값
            ,"hits" : # Query 결과를 표시
        }
    }
    

Range Query

  • 숫자, 날짜 형식들에 대한 range로 검색이 가능함
  POST users/_bulk
  {"index":{"_id":1}}
  {"user_name":"Jake","age":17,"date":"2023-01-04"}
  {"index":{"_id":2}}
  {"user_name":"Dean","age":23,"date":"2023-01-12"}
  {"index":{"_id":3}}
  {"user_name":"Mike","age":21,"date":"2022-09-15"}
  {"index":{"_id":4}}
  {"user_name":"Derek","age":54,"date":"2021-12-25"}
  {"index":{"_id":5}}
  {"user_name":"Josh","age":43,"date":"2022-06-31"}
  • range : { <필드명>: { <파라메터>:<값> } }

    • gte (Greater-than or equal to) - 이상 (같거나 큼)
    • gt (Greater-than) – 초과 (큼)
    • lte (Less-than or equal to) - 이하 (같거나 작음)
    • lt (Less-than) - 미만 (작음)
 GET users/_search
 {
   "query": {
     "range": {
       "age": {
         "gte": 21,
         "lt": 34
       }
     }
   }
 }
  • 날짜 검색

    • Json에서 일반적으로 사용되는 ISO8601 형식
 GET users/_search
 {
   "query": {
     "range": {
       "date": {
         "gt": "2023-01-01"
       }
     }
   }
 }

Bool Query

  • 여러 쿼리를 조합하기 위해서는 true, false 값을 갖는 bool 쿼리를 사용하고 다른 쿼리를 안에 넣어야 함

    • must: 쿼리가 true인 도큐먼트들을 검색
    • must_not: 쿼리가 false 도큐먼트들을 검색
    • should: 쿼리에 해당하는 도큐먼트들의 점수를 높임
    • filter: 쿼리가 true인 도큐먼트들을 검색, 스코어 계산은 하지 않음. 따라서, must보다 속도가 빠르고 캐싱 가능
 GET <인덱스명>/_search
 {
   "query": {
     "bool": {
       "must": [
         { <쿼리> }, …
       ],
       "must_not": [
         { <쿼리> }, …
       ],
       "should": [
         { <쿼리> }, …
       ],
       "filter": [
         { <쿼리> }, …
       ]
     }
   }
 }
 GET kibana_sample_data_ecommerce/_search
 {
   "query": {
     "bool": {
       "must": {
         "term" : { "customer_id": 4}
       },
       "filter": {
         "term": {"day_of_week":"Wednesday"}
       },
       
       "should": [
         {"term": { "customer_last_name":"Garza"}}
       ],
       "boost": 1 # 검색에 가중치를 부여
     }
   }
 }
  • range 쿼리와의 조합
 GET users/_search
 {
   "query": {
     "bool": {
       "must": {
         "range" :{
           "age": { "gte" : 21,
           "lte" : 55
           }
       }
     }
   }
 }
 }
 

Relevancy

  • 얼마나 정확한지에 대한 지표, 관련도
  • Score
    • 결과가 검색 조건과 얼마나 일치하는지를 나타냄, desc
    • BM25를 사용
    • TF, IDF, Field Length
      • TF(Term Frequency) : 특정 문서에서 특정 단어의 출현빈도
        • 도큐먼트 내에 텀이 많을수록 관련도가 높을 가능성이 있음
      • IDF(Inverse Document Frequency) : DF는 전체 문서들 중에서 해당 문서를 제외한 나머지 문서에서 해당 단어가 몇 번 사용되었는지를 의미
        • 검색한 텀을 포함하는 도큐먼트 개수가 많을 수록 텀에 대한 점수가 감소함, 텀이 증가할 수록 IDF 감소
      • Field Length : 도큐먼트에서 필드길이가 짧은 필드에 있는 텀의 중요도가 더 큼, 텍스트 길이가 짧은 필드에 검색어를 포함하면 점수가 더 높음

Full Text Query

  • 풀텍스트 쿼리를 사용하면 텍스트 필드를 검색할 수 있음

match

  • 텍스트와 매치되는 도큐먼드들을 검색할 수 있다.

  • text는 analyzer를 통해 분석된 후에 검색에 사용된다, 보통 Standard Analyzer가 기본으로 설정되어 있다

  GET users/_search
  {
      "query": {
          "match": {
              "user_name": {
                  "query" : "Jake Dean"
              }
          }
      }
  }
  • 기본적으로 OR로 검색이 되고 AND를 사용하고 싶다면 operator를 붙여준다
    GET users/_search
    {
        "query": {
            "match": {
                "user_name": {
                    "query" : "Jake Dean",
                    "operator": "and"
                }
            }
        }
    }
    

match-phrase query

  • 띄어쓰기까지 포함한 정확한 phrase를 검색할 때 사용됨
GET kibana_sample_data_ecommerce/_search
  {
    "query": {
      "match_phrase": {
        "customer_full_name": "Eddie Underwood"
      }
    }
  }
  • slop 설정 가능

    • 지정된 숫자만큼 단어 사이에 다른 검색어가 들어가는 것을 허용

multi-match query

  • 여러개의 필드에서 쿼리를 검색할 수 있음

  • 동일 쿼리를 여러 다른 필드에 match query를 사용한 것과 동일한 결과를 가져옴

  GET users/_search
  {
      "query": {
          "multi_match": {
              "query" : 21,
              "fields" : ["age", "user_name"]
          }
      }
  }

match all

  • 쿼리에 매치되는 모든 도큐먼트를 검색
GET users/_search
{
	"query": {"match_all": {}}
}