programing tip

ElasticSearch — 필드 값을 기반으로 관련성 향상

itbloger 2020. 11. 25. 07:43
반응형

ElasticSearch — 필드 값을 기반으로 관련성 향상


필드의 특정 값을 기반으로 문서의 관련성을 높이기 위해 ElasticSearch에서 방법을 찾아야합니다. 특히 모든 문서에는 필드 값이 높을수록 검색에 관계없이 포함 된 문서의 관련성이 높아야하는 특수 필드가 있습니다.

다음 문서 구조를 고려하십시오.

{
    "_all" : {"enabled" : "true"},
    "properties" : {
        "_id":            {"type" : "string",  "store" : "yes", "index" : "not_analyzed"},
        "first_name":     {"type" : "string",  "store" : "yes", "index" : "yes"},
        "last_name":      {"type" : "string",  "store" : "yes", "index" : "yes"},
        "boosting_field": {"type" : "integer", "store" : "yes", "index" : "yes"}
        }
}

boosting_field 값이 더 높은 문서가 boosting_field 값이 더 낮은 문서 보다 본질적으로 더 관련있기를 바랍니다 . 이것은 시작점 일뿐입니다. 검색에서 각 문서의 최종 관련성 점수를 결정할 때 쿼리와 다른 필드 간의 일치도 고려됩니다. 그러나 다른 모든 것이 동일할수록 부스팅 필드가 높을수록 문서의 관련성이 높아집니다 .

누구든지 이것을 수행하는 방법에 대한 아이디어가 있습니까?

감사합니다!


인덱스 시간 또는 쿼리 시간에 부스트 할 수 있습니다. 일반적으로 쿼리 속도가 약간 느려지더라도 쿼리 시간 부스팅을 선호합니다. 그렇지 않으면 부스팅 팩터를 변경할 때마다 다시 인덱싱해야하는데, 이는 일반적으로 미세 조정이 필요하고 매우 유연해야합니다.

elasticsearch 쿼리 DSL을 사용하여 쿼리 시간 부스팅을 적용하는 여러 가지 방법이 있습니다.

처음 세 개의 쿼리는 특정 쿼리 또는 필터와 일치하는 문서를 특정 수준으로 높이려는 경우에 유용합니다. 예를 들어 지난달에 게시 된 문서 만 부스트하려는 경우입니다. 이 접근 방식을 boosting_field와 함께 사용할 수 있지만 몇 가지 boosting_field 간격을 수동으로 정의하고 다른 부스트를 제공해야합니다.

가장 좋은 해결책은 스크립트를 사용하여 쿼리를 만들고 점수를 사용자 지정할 수 있는 Custom Score Query 를 사용하는 것 입니다. 스크립트를 사용하면 악보 자체를 직접 수정할 수 있으므로 매우 강력합니다. 우선, 예를 들어 boosting_field 값을 0에서 1까지의 값으로 조정하여 최종 점수가 큰 숫자가되지 않도록합니다. 이를 위해서는 필드에 포함될 수있는 최소값과 최대 값이 어느 정도인지 예측해야합니다. 예를 들어 최소 0과 최대 100000을 가정 해 보겠습니다. boosting_field 값을 0과 1 사이의 숫자로 조정하면 다음과 같이 결과를 실제 점수에 추가 할 수 있습니다.

{
    "query" : {
        "custom_score" : {
            "query" : {
                "match_all" : {}
            },
            "script" : "_score + (1 * doc.boosting_field.doubleValue / 100000)"
        }
    }
}

boosting_field를 부스트 팩터 ( _score *대신 _score +) 로 사용하는 것을 고려할 수도 있지만 최소값이 1 인 간격으로 확장해야합니다 (+1 만 추가하면 됨).

점수에 영향을 미치는 데 사용하는 값에 가중치를 추가하여 중요도를 변경하기 위해 결과를 조정할 수도 있습니다. 다른 가중치를 부여하기 위해 여러 부스팅 요소를 함께 결합해야하는 경우이 기능이 더 많이 필요할 것입니다.


최신 버전의 Elasticsearch (버전 1.3 이상)에서는 "함수 점수 쿼리"를 사용하고 싶을 것입니다.

http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html

점수가 매겨진 query_string 검색은 다음과 같습니다.

{
 'query': {
        'function_score': {
            'query': { 'query_string': { 'query': 'my search terms' } },
            'functions': [{ 'field_value_factor': { 'field': 'my_boost' } }]
        }
    }
}

"my_boost" is a numeric field in your search index that contains the boost factor for individual documents. May look like this:

{ "my_boost": { "type": "float", "index": "not_analyzed" } }

if you want to avoid to do the boosting each time inside the query, you might consider to add it to your mapping directly adding "boost: factor.

So your mapping then may look like this:

{
    "_all" : {"enabled" : "true"},
    "properties" : {
        "_id":            {"type" : "string",  "store" : "yes", "index" : "not_analyzed"},
        "first_name":     {"type" : "string",  "store" : "yes", "index" : "yes"},
        "last_name":      {"type" : "string",  "store" : "yes", "index" : "yes"},
        "boosting_field": {"type" : "integer", "store" : "yes", "index" : "yes", "boost" : 10.0,}
        }
}

If you are using Nest, you should use this syntax:

.Query(q => q
    .Bool(b => b
        .Should(s => s
            .FunctionScore(fs => fs
                .Functions(fn => fn
                    .FieldValueFactor(fvf => fvf
                        .Field(f => f.Significance)
                        .Weight(2)
                        .Missing(1)
        ))))
        .Must(m => m
            .Match(ma => ma
                .Field(f => f.MySearchData)
                    .Query(query)
))))

참고URL : https://stackoverflow.com/questions/12427449/elasticsearch-boosting-relevance-based-on-field-value

반응형