아빠는 개발자

[es] multi_match 쿼리와 Lucene 쿼리 구조 본문

Elastic/elasticsearch

[es] multi_match 쿼리와 Lucene 쿼리 구조

father6019 2023. 12. 23. 10:25
728x90
반응형

빠른 요약

multi_match 쿼리 구조는 analyzer 의 영향을 받는다 

 

쿼리 유형 multi_match

쿼리가 내부적으로 실행되는 방식은 다음과 같이 설정할 수 있는 매개변수에 multi_match따라 다릅니다

best_fields ( 기본값 ) 모든 필드와 일치하지만 _score가장 적합한 필드의 문서를 사용하는 문서를 찾습니다.
most_fields 모든 필드와 일치하는 문서를 찾아 _score각 필드의 문서를 결합합니다.
cross_fields analyzer필드를 하나의 큰 필드인 것처럼 동일하게 처리합니다 . 모든 필드 에서 각 단어를 찾습니다 
phrase match_phrase각 필드에 대해 쿼리를 실행 하고 _score 가장 적합한 필드를 사용합니다
phrase_prefix match_phrase_prefix각 필드에 대해 쿼리를 실행 하고 _score가장 적합한 필드를 사용합니다
bool_prefix match_bool_prefix각 필드에 대한 쿼리를 만들고 _score각 필드의 쿼리를 결합합니다.

 

이슈가 있었는데 무엇이냐 하면 "analyzer필드를 하나의 큰 필드인 것처럼 동일하게 처리"

recall_analyzer 가 생성/맵핑 되면서 Lucene 쿼리의 그룹핑이 달라짐

 

즉, analyzer 로 그룹핑 되던 쿼리구조가 달라져서 검색결과가 다르게 나옴

 

AS-IS TO-BE
+function score (
    (
        category.categorySearchKeyword:팔도컵라면 
        |
            (
                +(brandNmEng:paldo | brandNmEng:팔도 | itemOptionNms:paldo | itemOptionNms:팔도 | promoKeyword:paldo | promoKeyword:팔도 | itemStoreInfo.eventInfo.eventKeyword:paldo | itemStoreInfo.eventInfo.eventKeyword:팔도 | searchItemNm:paldo | searchItemNm:팔도 | brandNmKor:paldo | brandNmKor:팔도) 
                +(
                    ( 
                        +(brandNmEng:사발 | itemOptionNms:사발 | promoKeyword:사발 | itemStoreInfo.eventInfo.eventKeyword:사발 | searchItemNm:사발 | brandNmKor:사발)
                        +(brandNmEng:면 | itemOptionNms:면 | promoKeyword:면 | itemStoreInfo.eventInfo.eventKeyword:면 | searchItemNm:면 | brandNmKor:면)
                    ) 
                    (
                        +(brandNmEng:컵 | itemOptionNms:컵 | promoKeyword:컵 | itemStoreInfo.eventInfo.eventKeyword:컵 | searchItemNm:컵 | brandNmKor:컵)
                        +(brandNmEng:라면 | itemOptionNms:라면 | promoKeyword:라면 | itemStoreInfo.eventInfo.eventKeyword:라면 | searchItemNm:라면 | brandNmKor:라면)
                    )
                )
            )
        | 
            (isbn:팔도 컵라면 | itemNo:팔도 컵라면 | searchKeywordPromo:팔도 컵라면 | searchKeywordRecomMsg:팔도 컵라면) 
        | 
            (
                +(searchKeyword:paldo | searchKeyword:팔도 | category.dcateNm:paldo | category.dcateNm:팔도) 
                +(
                    (+(searchKeyword:사발 | category.dcateNm:사발) +(searchKeyword:면 | category.dcateNm:면))
                    (+(searchKeyword:컵 | category.dcateNm:컵) +(searchKeyword:라면 | category.dcateNm:라면))
                )
            )
    ), functions: []
)
+function score (
(
category.categorySearchKeyword:팔도컵라면 

    (
        +(brandNmEng:paldo | brandNmEng:팔도 | itemOptionNms:paldo | itemOptionNms:팔도 | promoKeyword:paldo | promoKeyword:팔도 | itemStoreInfo.eventInfo.eventKeyword:paldo | itemStoreInfo.eventInfo.eventKeyword:팔도 | searchKeyword:paldo | searchKeyword:팔도 | category.dcateNm:paldo | category.dcateNm:팔도 | searchItemNm:paldo | searchItemNm:팔도 | brandNmKor:paldo | brandNmKor:팔도)
        +(
            (
                +(brandNmEng:사발 | itemOptionNms:사발 | promoKeyword:사발 | itemStoreInfo.eventInfo.eventKeyword:사발 | searchKeyword:사발 | category.dcateNm:사발 | searchItemNm:사발 | brandNmKor:사발) +(brandNmEng:면 | itemOptionNms:면 | promoKeyword:면 | itemStoreInfo.eventInfo.eventKeyword:면 | searchKeyword:면 | category.dcateNm:면 | searchItemNm:면 | brandNmKor:면)
            )
            (
                +(brandNmEng:컵 | itemOptionNms:컵 | promoKeyword:컵 | itemStoreInfo.eventInfo.eventKeyword:컵 | searchKeyword:컵 | category.dcateNm:컵 | searchItemNm:컵 | brandNmKor:컵)
                +(brandNmEng:라면 | itemOptionNms:라면 | promoKeyword:라면 | itemStoreInfo.eventInfo.eventKeyword:라면 | searchKeyword:라면 | category.dcateNm:라면 | searchItemNm:라면 | brandNmKor:라면)
            )
        )
    )
|
    (isbn:팔도 컵라면 | itemNo:팔도 컵라면 | searchKeywordPromo:팔도 컵라면 | searchKeywordRecomMsg:팔도 컵라면)
)
, functions: []
)

 

동일한 분석기가 있는 필드에서 동작 하는데 그룹핑이 달라지면서 and 와 or 의 구조가 달라진것이다. 

해결방법은 맵핑된 analyzer를 수정하면서 원하는 구조로 맞추면 된다. 

728x90
반응형