elasticsearch score로 정렬(sorting)

개발새발·2023년 1월 1일
0

elasticsearch

목록 보기
35/54

일반 sort에서 _script 로는 성능이 너무 나오지 않아서 다른 방법을 강구해보다가 같은 팀원분이 score로도 sort가 가능하니 그걸로 해보자는 의견을 주셔서 바로 실행해봤다.

방법

두가지 방법이 있었다.

1.function_score 안에 script_sort 사용

QUERY문

 {
                 "script_fields": {
                     "field1": {
                         "script": {
                             "lang": "painless",
                             "source": "params['_source']['field2'].findAll(t -> t.nested == 'test')"
                         }
                     }
                 },
                 "query": {
                     "function_score": {
                         "query": {
                             "bool": {
                                 "must": [
                                     {
                                         "terms": {
                                             "_index": [
                                                 "index"
                                             ]
                                         }
                                     }
                                 ],
                                 "filter": {
                                     "bool": {
                                         "must": [
                                             {
                                                 "term": {
                                                     "fieldA": false
                                                 }
                                             },
                                             {
                                                 "term": {
                                                     "fieldB": true
                                                 }
                                             }
                                         ]
                                     }
                                 }
                             }
                         },
                         "script_score": {
                             "script": {
                                 "params": {"a": 1, "b": 2, "c": 3},
                                 "source": "doc['fieldC'].value * params.a + doc['fieldD'].value * params.b + doc['fieldF'].value * params.c"
                             }
                         }
                     }
                 },
                 "_source": [
                     "field1",
 										"field2"
                 ],
                 "sort": {
                     "_score": {
                         "order": "desc"
                     }
                 },
                 "size": 100,
                 "from": 0
             }

query 아래 부분에 function_scorescript_score, 그리고 sort 부분 주목!


2. function_score 안에 field_value_factor 사용

QUERY문

    {
     
        "script_fields": {
                        "field1": {
                            "script": {
                                "lang": "painless",
                                "source": "params['_source']['field2'].findAll(t -> t.nested == 'test')"
                            }
                        }
                    },
                    "query": {
                        "function_score": {
                            "query": {
                                "bool": {
                                    "must": [
                                        {
                                            "terms": {
                                                "_index": [
                                                    "index"
                                                ]
                                            }
                                        }
                                    ],
                                    "filter": {
                                        "bool": {
                                            "must": [
                                                {
                                                    "term": {
                                                        "fieldA": false
                                                    }
                                                },
                                                {
                                                    "term": {
                                                        "fieldB": true
                                                    }
                                                }
                                            ]
                                        }
                                    }
                                }
                            },
                            "functions": [
                                {
                                    "field_value_factor": {
                                        "field": "fieldC",
                                        "factor": 1,
                                        "missing": 0
                                    }
                                },
                                {
                                    "field_value_factor": {
                                        "field": "fieldD",
                                        "factor": 2,
                                        "missing": 0
                                    }
                                },
                                {
                                    "field_value_factor": {
                                        "field": "fieldF",
                                        "factor": 3,
                                        "missing": 0
                                    }
                                }
                            ],
                            "score_mode": "sum",
                            "boost_mode" : "replace"
                        }
                    },
                    "_source": [
                        "field1",
    										"field2"
                    ],
                    "sort": {
                        "_score": {
                            "order": "desc"
                        }
                    },
                    "size": 100,
                    "from": 0
                }

query 아래 부분에 function_scorefunctions, 그리고 sort 부분 주목!
functions 는 사용방법이 신기했다. 각 field_value_factor 를 토대로 하여 score가 계산된다. factor은 가중치라고 볼 수 있고, score_mode 는 각 field_value_factor 에 대한 처리를 의미한다. 또한, boost_mode 는 쿼리 결과의 스코어와 결합을 어떻게 할지에 대한 처리를 의미한다.

성능

둘다 esrally 로 돌려봤는데, 2번 방법의 처리량이 훨씬 좋았다. 처리량차이가 200배정도 났다.

profile
발새발개

0개의 댓글