#elasticsearch #lucene
#elasticsearch #lucene
Вопрос:
Допустим, мы отправляем запрос (точный тип не имеет значения) для термина: «cosmopolitan» в определенном поле, и давайте предположим, что результирующий набор содержит несколько документов, каждый из которых содержит ровно «k» экземпляров «cosmopolitan».
Каким бы ни был применимый механизм (повышение, взвешивание, сортировка и т. Д.), Я бы хотел, Чтобы результирующий набор возвращался таким образом, чтобы учитывались позиции «cosmopolitan» в документах, т.Е. Если средняя позиция cosmopolitan ниже (ближе к началу документа), то его ранг/ оценка выше.
Я изучил различные типы запросов и сценариев, но, похоже, не могу найти что-то, что применимо к этому, что кажется странным, поскольку для многих доменов термин position может быть действительно важным.
Ответ №1:
Если мы говорим о точных подстроках произвольного myfield
, мы можем использовать скрипт сортировки, который вычитает индекс первого вхождения из всей длины строки, тем самым увеличивая более ранние вхождения:
{
"query": { ... },
"sort": [
{
"_script": {
"script": {
"params": {
"substr_value": "cosmopolitan"
},
"source": """
def fieldval = doc['myfield.keyword'].value;
def indexof = fieldval.indexOf(params.substr_value);
return indexof == -1 ? _score : _score (fieldval.length() - indexof)
"""
},
"type": "number",
"order": "desc"
}
}
]
}
.keyword
Сопоставление не требуется — поле тоже могло иметь fielddata: true
настройку — в любом случае, нам понадобится доступ к исходному значению myfield
, чтобы этот скрипт работал.
В качестве альтернативы, здесь отлично подходит запрос оценки функции:
{
"query": {
"function_score": {
"query": {
"match": {
"myfield": "cosmopolitan"
}
},
"script_score": {
"script": {
"params": {
"substr_value": "cosmopolitan"
},
"source": """
def fieldval = doc['myfield.keyword'].value;
def indexof = fieldval.indexOf(params.substr_value);
return indexof == -1 ? _score : (fieldval.length() - indexof)
"""
}
},
"boost_mode": "sum"
}
}
}
Вы можете настроить его параметры, такие как boost_mode
, weight
и т.д., в соответствии с вашими потребностями.
Кроме того, вы, вероятно, захотите выполнить взвешенное среднее значение всех вхождений подстроки, и вы можете сделать это в этих сценариях.
Комментарии:
1. Спасибо, это было очень полезно. Я действительно ценю это.
2. Приятно, рад это слышать! Привет, я пишу руководство по Elasticsearch и хотел бы услышать ваш вклад . Приветствия!
3. ПРИМЕЧАНИЕ: если для track_sores не установлено значение true на верхнем уровне запроса, _score всегда будет равен 0 для сценария контекста сортировки, поскольку ES не будет утруждать себя вычислением оценки (это дорого, и ES предполагает, что вы все равно переопределяете его).