elasticsearch

elasticsearch function_score

천천히올라가자 2021. 2. 22. 20:11
반응형

전에 사용했던 similarity를 function_score로 구현해볼 것이며 similarity는 아래 링크를 참조하자

https://ksk-developer.tistory.com/25

function_score는 score를 조작 할 수 있도록 해주고 기본 적으로 tf-idf와 bm25를 사용하게 되는데 현재 요구사항에는 그것 때문에 적용이 되지 않았다 그래서 score를 조작할 수 있는 function_score를 사용하기로 하였다 아래 코드는 실제 동작하는 코드이지만 필드명과 쿼리의 상당부분을 제거와 변경하였다

GET test/_search
{
  "from": 0,
  "size": 10,
  "timeout": "200ms",
  "query": {
    "function_score": {
      "query": {
        "bool": {
          "must": [
            {
              "bool": {
                "should": [
                  {
                    "multi_match": {
                      "query": "n",
                      "fields": [
                        "name^0.0"
                      ],
                      "type": "phrase",
                      "operator": "AND"
                    }
                  }
                ]
              }
            }
          ]
        }
      },
      "functions": [
        {
          "script_score": {
            "script": {
              "source": "doc['rank'].value + _score ",
              "lang": "painless"
            }
          }
        },
        {
          "weight": 5000, 
          "filter": {
            "bool": {
              "should": [
                {
                  "match": {
                    "name": {
                      "query": "n",
                      "operator": "OR"
                    }
                  }
                },
                {
                  "match": {
                    "english_name": {
                      "query": "n",
                      "operator": "OR"
                    }
                  }
                }
              ]
            }
          }
        },
        {
          "weight": 10000, 
          "filter": {
            "bool": {
              "should": [
                {
                  "match": {
                    "name": {
                      "query": "n",
                      "operator": "OR"
                    }
                  }
                },
                {
                  "match": {
                    "english_name": {
                      "query": "n",
                      "operator": "OR"
                    }
                  }
                }
              ]
            }
          }
        }
      ],
      "score_mode": "sum",
      "boost_mode": "replace",
      "max_boost": 3.4028235e+38,
      "boost": 1
    }
  },
  "_source": {
    "includes": [
      "name"
    ],
    "excludes": []
  }
}

위와 같이 functions 내에서 weight 값을 주면 script_score의 source에서 _score에 반영이 된다 그것을 이용해서 정렬을 사용하면 된다

위와 같은 코드는 의사코드로 보면 될 것 같고 완전 매칭시 1만의 score를 부분 매칭시 5천의 score 값을 준다

두개다 매칭이 될 경우에는 1만5천이 되는 것이며 rank까지 합산한 결과로 정렬을 한다

 

factor: 0.5 설정한 필드의 값에 0.5를 곱함

missing: 0.01 해당 필드에 값이 없으면 0.01이 기본 값

boost_mode: replace는 functions에 있는 score만 사용하겠다는 것이다

score_mode: functions에 있는 스코어를 합한다는 의미이다

 

 

더 많은 기능은 아래 링크를 참조해서 확인해보기 바란다

 

참조

www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#function-random

반응형