Вопрос по search, elasticsearch – ElasticSearch - повышение релевантности на основе значения поля

60

Нужно найти способ в 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 былиinherently more relevant чем с более низким значением boosting_field. Это только отправная точка - соответствие между запросом и другими полями также будет учитываться при определении итоговой оценки релевантности каждого документа в поиске. Но,all else being equal, the higher the boosting field, the more relevant the document.

У кого-нибудь есть идеи, как это сделать?

Большое спасибо!

Смотрите такжеstackoverflow.com/a/41813578/5444623 для различного усиления по полю типов документов PeterM

Ваш Ответ

3   ответа
3

вы можете добавить его в свое отображение, добавив непосредственно Boost: factor.

Таким образом, ваше отображение может выглядеть так:

{
    "_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,}
        }
}
Добавление его к запросу - это не просто дублирование, это увеличение времени запроса, которое вы можете изменять каждый раз, в то время как если вы добавляете повышение к своему отображению, которое увеличивает время индекса, вам нужно переиндексировать его, чтобы изменить его. Я всегда рекомендую увеличение времени запроса по сравнению с увеличением времени индекса.
13

ть" запросы на оценку функции ":

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

Поиск с оценкой по запросу выглядит так:

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

& Quot; my_boost & Quot; является числовым полем в вашем поисковом индексе, который содержит коэффициент повышения для отдельных документов. Может выглядеть так:

{ "my_boost": { "type": "float", "index": "not_analyzed" } }
Это работает только на первой странице!
68

предпочитаю увеличение времени запроса, даже если оно делает запросы немного медленнее, в противном случае мне нужно будет переиндексировать каждый раз, когда я хочу изменить свои факторы повышения, которые обычно требуют точной настройки и должны быть достаточно гибкими.

Существуют различные способы применить увеличение времени запроса с помощью DSL-запроса ввода-вывода:

Boosting Query Custom Filters Score Query Custom Boost Factor Query Custom Score Query

Первые три запроса полезны, если вы хотите придать конкретный импульс документам, которые соответствуют определенным запросам или фильтрам. Например, если вы хотите повысить только те документы, которые были опубликованы за последний месяц. Вы можете использовать этот подход с вашим boosting_field, но вам нужно вручную определить некоторые интервалы boosting_field и дать им другое повышение, что не так уж и велико.

Лучшее решение будет использоватьПользовательский запрос счета, что позволяет сделать запрос и настроить его счет с помощью скрипта. Он довольно мощный, с помощью скрипта вы можете напрямую изменять сам счет. Прежде всего, я масштабирую значения 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).

Вы можете даже настроить результат, чтобы изменить его важность, добавив вес к значению, которое вы используете, чтобы повлиять на оценку. Вам это понадобится еще больше, если вам нужно объединить несколько повышающих факторов вместе, чтобы придать им другой вес.

Вы можете использоватьfiltered query и добавить к нему как запрос, так и фильтр, например.
Правда, теперь есть один запрос, чтобы управлять ими всеми:function_score запрос.
Вы можете разместить и отфильтровать в custom_score. Прямо сейчас ваш запрос только match_all, можете ли вы добавить и отфильтровать его.
К сожалению, большинство из предложенных методов устарели ...
Но это не поможет цели. То, что вы пишете в примере, хорошо для меня, но нужно добавить один фильтр в основной запрос.,

Похожие вопросы