기존에 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 쿼리의 차이였다.
query_string
텍스트 기반의 쿼리를 처리하기 위해 사용
Lucene의 DisjunctionMaxQuery
를 기반으로 동작
입력된 쿼리 문자열을 분석하고, 각 토큰에 대해 해당 토큰이 문서에 얼마나 일치하는지 계산 → 토큰의 일치도에 따라 개별적인 스코어가 계산되고, 이러한 개별 스코어 중 가장 높은 스코어가 전체 문서의 스코어로 사용
query_string
쿼리의 스코어는 해당 쿼리에 대한 가장 높은 토큰 일치도를 반영
*토큰 : 텍스트를 작은 단위로 분할한 결과물
match
단순히 특정 필드에서 텍스트를 검색하는 데 사용되는 쿼리
텍스트를 분석하여 해당 필드의 용어와 일치하는 문서를 찾음 → 일치하는 문서는 각 용어의 일치도에 따라 스코어가 계산되고, 이러한 개별 스코어의 합계가 문서의 최종 스코어로 사용
match
쿼리의 스코어는 해당 필드에 대한 용어 일치도를 반영
*용어: 텍스트 처리나 정보 검색에서 사용되는 실제 용어 또는 단어