본문 바로가기

programmer/Elasticsearch

[Elasticsearch] 거리 가중치에 따른 Score 집계 방법

ELK에서 거리 가중치에 따라 score를 받고 싶을 때 사용한다.

하기 쿼리와 같이 "function_score"를 사용하면 거리 별 스코어를 받아 볼 수 있다.(linear 사용)

three decay functions together with their parameters can be visualized

 

GET your_index_name/_search
{
   "query": {
    "function_score": {
      "functions": [
        {
           "linear": {#decay 함수 명
        "center": { #좌표 필드 명
          "origin": [ 127.00493315155632, 37.57582519652989], 
          "scale": "2km",
          "offset": "0km",         
          "decay": 0.33            
        }
      }
        }
      ],
      "query": {
    "bool": {
      "must": [
        {
          "dis_max": {
            "tie_breaker": 0,
            "queries": [
              {
                "terms": {
                  "poi_code": [#조건 필드
                    "9732"
                  ],
                  "boost": 1
                }
              }
            ],
            "boost": 1
          }
        },
        {
          "exists": {
            "field": "field_name_1",
            "boost": 1
          }
        },
        {
          "exists": {
            "field": "field_name_2",
            "boost": 1
          }
        }
      ]
    }
      },
      "score_mode": "multiply"
    }
  }
}

결과

이전 쿼리

GET your_index_name/_search
{
  "from": 0,
  "size": 50,
  "timeout": "2700ms",
  "query": {
    "function_score": {
      "query": {
        "bool": {
          "must": [
            {
              "dis_max": {
                "tie_breaker": 0,
                "queries": [
                  {
                    "terms": {
                      "poi_code": [
                        "9732"
                      ]
                    }
                  }
                ]
              }
            },
            {
              "exists": {
                "field": "field_name_1"
              }
            },
            {
              "exists": {
                "field": "field_name_2"
              }
            }
          ],
          "filter": [
            {
              "geo_distance": {
                "center": [
                  127.005075,
                  37.57588611
                ],
                "distance": 2000,
                "distance_type": "arc",
                "validation_method": "STRICT",
                "ignore_unmapped": false
              }
            }
          ],

          "adjust_pure_negative": true
        }
      },
      "functions": [
        {
          "linear": {
            "center": {
              "origin": "37.57588611,127.005075",
              "scale": "100m",
              "offset": "0km",
              "decay": 0.800000011920929
            },
            "multi_value_mode": "MIN"
          }
        }
      ],
      "score_mode": "multiply",
      "max_boost": 3.4028235e+38
    }
  }
}

결과

코드로 보면 하기와 같다.

/**
 * offset: origin으로부터 스코어가 줄어들지 않는 구간의 거리.
 * scale & decay:이 두값의 조합으로 스코어 값이 줄어드는 기준이 정해진다.
 * 예를 들어, scale값이 100m, decay값이 0.8f, offset 값은 0m이면 origin에서부터 0m 부터 1km 멀어질수록 스코어가 0.8배 줄어든다.
 */

FunctionScoreQueryBuilder.FilterFunctionBuilder[] functions = {
        new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                ScoreFunctionBuilders.linearDecayFunction("center", request.getBasePos(), "100m", "0m", 0.8f)
        )
};
QueryBuilder builder = QueryBuilders.functionScoreQuery(baseQuery, functions);

 

참고로 쿼리에 "track_scores" : true"를 추가하면 score 값을 확인 할 수 있다.

 

참조 링크

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

반응형
사업자 정보 표시
라울앤알바 | 장수호 | 서울특별시 관악구 봉천로 13나길 58-10, 404호(봉천동) | 사업자 등록번호 : 363-72-00290 | TEL : 010-5790-0933 | Mail : shjang@raulnalba.com | 통신판매신고번호 : 2020-서울관악-0892호 | 사이버몰의 이용약관 바로가기