본문 바로가기

Elastic Search

[Elastic Search] MBTI 검색 프로젝트 - 1. 검색 Score 튜닝

반응형

현재 엘라스틱서치를 이용해 수집한 데이터(MBTI 타입별 텍스트 데이터)를 조회하는 프로젝트를 진행하고 있습니다. 여기서 MBTI 타입과 스마트폰(아이폰 또는 갤럭시)의 상관성을 분석하기 위해 ES의 쿼리를 튜닝하고 있습니다.

 

인덱스 구성

콘텐츠 내부에서 명사만 추출하여 분석하기 위해 nori_noun이라는 분석기를 별도로 생성하여 필드로 설정했습니다.

{
  "mbti" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "comment_cnt" : {
          "type" : "integer"
        },
        "contents" : {
          "type" : "text",
          "fields" : {
            "full" : {
              "type" : "keyword"
            },
            "nori_mixed" : {
              "type" : "text",
              "analyzer" : "nori_mixed",
              "search_analyzer" : "standard"
            },
            "nori_noun" : {
              "type" : "text",
              "analyzer" : "nori_pos_noun",
              "search_analyzer" : "standard"
            }
          }
        },
        "doc_url" : {
          "type" : "text"
        },
        "keyword" : {
          "type" : "keyword"
        },
        "like_cnt" : {
          "type" : "integer"
        },
        "platform" : {
          "type" : "keyword"
        },
        "published_at" : {
          "type" : "date"
        },
        "title" : {
          "type" : "text"
        },
        "writer" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "routing" : {
          "allocation" : {
            "include" : {
              "_tier_preference" : "data_content"
            }
          }
        },
        "number_of_shards" : "1",
        "provided_name" : "mbti",
        "creation_date" : "1649761141991",
        "analysis" : {
          "filter" : {
            "pos_filter" : {
              "type" : "nori_part_of_speech",
              "stoptags" : [
                "VV",
                "VA",
                "VX",
                "VCP",
                "VCN",
                "MM",
                "MAG",
                "MAJ",
                "IC",
                "J",
                "E",
                "XPN",
                "XSA",
                "XSN",
                "XSV",
                "SP",
                "SSC",
                "SSO",
                "SC",
                "SE",
                "UNA"
              ]
            }
          },
          "analyzer" : {
            "nori_mixed" : {
              "filter" : "shingle",
              "tokenizer" : "nori_t_mixed"
            },
            "nori_pos_noun" : {
              "filter" : "pos_filter",
              "type" : "custom",
              "tokenizer" : "nori_t_mixed"
            }
          },
          "tokenizer" : {
            "nori_t_mixed" : {
              "type" : "nori_tokenizer",
              "decompound_mode" : "mixed"
            }
          }
        },
        "number_of_replicas" : "1",
        "uuid" : "e8w9oHlLSyqF5oDzviz0KA",
        "version" : {
          "created" : "7170299"
        }
      }
    }
  }
}

각 MBTI 타입별 스마트폰 선호도

GET mbti/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "contents.nori_noun": {
              "query": "ENFP"
            }
          }
        },
        {
          "match_phrase": {
            "contents": {
              "query": "아이폰",
              "boost": 2
            }
          }
        }
        ]
    }
  }
}

Match 쿼리에 콘텐츠 내부에 MBTI 타입이 있는지에 대해 우선 조회한다. 그리고 match_phrase로 아이폰에 boost를 하여 아이폰이 포함된 원문이 상위 검색되도록 쿼리를 만들었습니다.

사실 match_phrase 는 구문, 즉 “아이폰 꿀팁”처럼 구문의 매칭 정도를 boost 해주기 때문에 위 사례에서는 적절한 사용 사례는 아닙니다. 원래는 “ENFP 아이폰”으로 검색하여 각 단어 간의 Distance를 검색 Score 알고리즘으로 사용하려고 했지만 실패하여 우선 match_phrase를 사용하였습니다.

 

해결방법은? (아래부터는 삽질의 역사입니다...)

#1 Should 를 사용한 조회

Should의 경우 흔히 말하는 or 조건으로 조건에 포함된 단어가 상위로 올라오도록(즉 score 점수가 더 높아질 수 있도록) 쿼리 변경

GET mbti/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "contents.nori_noun": {
              "query": "ENFP"
            }
          }
        }
        ],
      "should": [
        {
          "match": {
            "contents": {
              "query": "아이폰",
              "boost": 2
            }
          }
        },
        {
          "match": {
            "contents": {
              "query": "ENFP",
              "boost": 1
            }
          }
        }
        ]
    }
  }
}
반응형