[Elasticsearch] multi_match type 종류

ehwnghks·2023년 4월 9일

multi_match 기본 쿼리.

GET /_search
{
  "query": {
    "multi_match" : {
      "query":    "this is a test", 
      "fields": [ "subject", "message" ] 
    }
  }
}

multi_match type 종류


best_fields

(디폴트) match되는 fields 중에 가장 _score가 높은 field를 사용한다.

phrase / phrase_prefix

phrase, phrase_prefix type은 best_fields와 동일하게 작동하지만 match 쿼리 대신 match_phrase 또는 match_phrase_prefix 쿼리를 사용한다.

most_fields

most_fields는 지정된 모든 필드를 각각 match query 검색하는 거와 같다.

GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "quick brown fox",
      "type":       "most_fields",
      "fields":     [ "title", "title.original", "title.shingles" ]
    }
  }
}

이런 multi_match 쿼리는 다음과 같이 실행됨.

GET /_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "title":          "quick brown fox" }},
        { "match": { "title.original": "quick brown fox" }},
        { "match": { "title.shingles": "quick brown fox" }}
      ]
    }
  }
}

이런 특성으로 best_fields 와 most_fields type은 필드 중심으로 적용된다.
필드 마다 match쿼리를 생성하고 operator 와 minimum_should_match 적용 대상이 필드이다.
cross_fields는 적용 대상이 term(용어)이다.

GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "Will Smith",
      "type":       "best_fields",
      "fields":     [ "first_name", "last_name" ],
      "operator":   "and" 
    }
  }
}

위 쿼리 실행 시
(+first_name:will +first_name:smith)
| (+last_name:will +last_name:smith)

위 조건을 만족하는 문서가 검색 (필드 중심)
따라서, best_fields와 most_fields는 operator와 minimum_should_match 적용 시 한 필드에 모든 용어가 있어야 한다.

cross_fields

cross_fields는 지정된 필드를 큰 하나의 필드로 보고 검색을 한다.
예를들어,

GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "Will Smith",
      "type":       "best_fields",
      "fields":     [ "first_name", "last_name" ],
      "operator":   "and" 
    }
  }
}

위의 best_fields, most_fields와 달리
cross_fields type은 용어 중심

+(first_name:will last_name:will)
+(first_name:smith last_name:smith)

cross_fields type은 동일한 analyzer로 되어있는 필드들을 검색하기를 권장.

GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "Jon",
      "type":       "cross_fields",
      "fields":     [
        "first", "first.edge",
        "last",  "last.edge"
      ]
    }
  }
}

위와 같은 쿼리는
blended("jon", fields: [first, last])
| (
blended("j", fields: [first.edge, last.edge])
blended("jo", fields: [first.edge, last.edge])
blended("jon", fields: [first.edge, last.edge])
)

first,last 그룹과 *.edge 필드 그룹을 각각 단일 필드로 취급된다.
cross_fields도 다른 analyzer가 포함된 필드들을 검색할 때 operator와 minimum_should_match 문제가 발생할 수 있다.

GET /_search
{
  "query": {
    "bool": {
      "should": [
        {
          "multi_match" : {
            "query":      "Will Smith",
            "type":       "cross_fields",
            "fields":     [ "first", "last" ],
            "minimum_should_match": "50%" 
          }
        },
        {
          "multi_match" : {
            "query":      "Will Smith",
            "type":       "cross_fields",
            "fields":     [ "*.edge" ]
          }
        }
      ]
    }
  }
}

위와 같이 bool 쿼리로 동일 analyzer끼리 묶고 minimum_should_match를 그 중 하나에만 적용할 수 있다.

analyzer를 설정해 필드를 동일한 그룹으로 강제 설정할 수 있다.

GET /_search
{
  "query": {
   "multi_match" : {
      "query":      "Jon",
      "type":       "cross_fields",
      "analyzer":   "standard", 
      "fields":     [ "first", "last", "*.edge" ]
    }
  }
}
profile
반갑습니다.

0개의 댓글