elasticsearch match vs query_string 의 score 계산법

개발새발·2023년 6월 18일
0

elasticsearch

목록 보기
51/54

기존에 match 쿼리를 쓰다가 최근 query_string 쿼리를 사용하는 것을 검토할 일이 생겼다. 그런데 결과가 생각한거랑 다르게 나왔다.

💁‍♀️사전 테스트

  • 조회
{
     "_source" : [
         "A",
         "B"
     ],
     "query": {
         "bool": {
             "must": [
                 {
                     "query_string": {
                         "query": "체리샴푸 소중한시간 라운드카라 맨투맨",
                         "fields": [
                             "A",
                             "B"
                         ],
                         "default_operator": "OR",
                         "boost": 2
                     }
                 }
             ]
         }
     },
     "size": 10,
     "from": 0,
     "sort": [
         "_score"
     ]
 }
  • 결과

  [
	          {// 1...(생략)
                 "_score": 45.30889,
                 "_source": {
                     "A": "체리샴푸",
                     "B": "오비츠11 체크 팬츠"
                 }
             },
             {// 2...(생략)
                 "_score": 44.827927,
                 "_source": {
                     "A": "체리샴푸",
                     "B": "오비츠11 세일러 카라 맨투맨"
                 }
             },
             {// 3...(생략)
                 "_score": 44.197865,
                 "_source": {
                     "A": "체리샴푸",
                     "B": "오비츠11 라운드카라 맨투맨"
                 }
             }
]

내가 예상했던 결과는, 3번이 먼저 나오는 것이였다. 왜냐하면.. 아직 체리샴푸 소중한시간 라운드카라 맨투맨 에서 라운드카라 , 맨투맨 두 단어가 모두 B에 나왔기 때문이다. 그런데 결과를 보면 1번이 scoring이 가장 높다.

🌿과정

BM25 계산법에 의해서 그렇겠지..? 하다가 문득 기존에 match쿼리로 다시 조회를 해봤다.

  • 조회
{
     "_source" : [
         "A",
         "B"
     ],
     "query": {
         "bool": {
             "should": [
                 {
                     "match": {
                         "A": "체리샴푸 소중한시간 라운드카라 맨투맨"
                     }
                 },
                 {
                     "match": {
                         "B": "체리샴푸 소중한시간 라운드카라 맨투맨"
                     }
                 }
             ]
         }
     },
     "size": 10,
     "from": 0,
     "sort": [
         {
             "_score": "desc"
         }
     ]
 }
  • 결과
[
             {// 1... (생략)
                 "_score": 34.543736,
                 "_source": {
                     "A": "체리샴푸",
                     "B": "오비츠11 라운드카라 맨투맨"
                 }
             },
             {// 2... (생략)
                 "_score": 32.27543,
                 "_source": {
                     "A": "체리샴푸",
                     "B": "오비츠11 세일러 카라 맨투맨"
                 }
             },
             {// 3... (생략)
                 "_score": 28.610643,
                 "_source": {
                     "A": "체리샴푸",
                     "B": "26cm 구체관절인형 USD 세일러 카라 맨투맨"
                 }
             }
 ]

에엥? 그랬더니 내가 예상했던 것처럼 1번이 나온다. ㅋㅋㅋ scoring도 달라짐.. 결국 키는 match 쿼리와 query_string 쿼리의 차이였다.


💅match vs query_string 스코어 계산방법

  • query_string

    텍스트 기반의 쿼리를 처리하기 위해 사용

    Lucene의 DisjunctionMaxQuery를 기반으로 동작

    입력된 쿼리 문자열을 분석하고, 각 토큰에 대해 해당 토큰이 문서에 얼마나 일치하는지 계산 → 토큰의 일치도에 따라 개별적인 스코어가 계산되고, 이러한 개별 스코어 중 가장 높은 스코어가 전체 문서의 스코어로 사용

    query_string 쿼리의 스코어는 해당 쿼리에 대한 가장 높은 토큰 일치도를 반영

    *토큰 : 텍스트를 작은 단위로 분할한 결과물


  • match

    단순히 특정 필드에서 텍스트를 검색하는 데 사용되는 쿼리

    텍스트를 분석하여 해당 필드의 용어와 일치하는 문서를 찾음 → 일치하는 문서는 각 용어의 일치도에 따라 스코어가 계산되고, 이러한 개별 스코어의 합계가 문서의 최종 스코어로 사용

    match 쿼리의 스코어는 해당 필드에 대한 용어 일치도를 반영

    *용어: 텍스트 처리나 정보 검색에서 사용되는 실제 용어 또는 단어


⇒ 즉, 자세한 건 더 찾아봐야겠지만 query_string은 토큰 단위, match는 용어 단위로 스코어를 계산하기 때문에 둘의 계산법은 다르다.
profile
발새발개

0개의 댓글