Запрос с оценкой скрипта
Используйте запрос script_score
, чтобы настроить расчет оценки, используя скрипт. Для вычислительно затратной функции оценки вы можете использовать запрос script_score
, чтобы вычислить оценку только для возвращенных документов, которые были отфильтрованы.
Пример
Например, следующий запрос создает индекс, содержащий один документ:
PUT testindex1/_doc/1
{
"name": "John Doe",
"multiplier": 0.5
}
Вы можете использовать запрос match
, чтобы вернуть все документы, содержащие “John” в поле имени:
GET testindex1/_search
{
"query": {
"match": {
"name": "John"
}
}
}
В ответе документ 1 имеет оценку 0.2876821:
{
"took": 7,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.2876821,
"hits": [
{
"_index": "testindex1",
"_id": "1",
"_score": 0.2876821,
"_source": {
"name": "John Doe",
"multiplier": 0.5
}
}
]
}
}
Теперь давайте изменим оценку документа, используя скрипт, который вычисляет оценку как значение поля _score
, умноженное на значение поля multiplier
. В следующем запросе вы можете получить текущую релевантность документа в переменной _score
, а значение множителя как doc['multiplier'].value
:
GET testindex1/_search
{
"query": {
"script_score": {
"query": {
"match": {
"name": "John"
}
},
"script": {
"source": "_score * doc['multiplier'].value"
}
}
}
}
В ответе оценка для документа 1 составляет половину от первоначальной оценки:
{
"took": 8,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.14384104,
"hits": [
{
"_index": "testindex1",
"_id": "1",
"_score": 0.14384104,
"_source": {
"name": "John Doe",
"multiplier": 0.5
}
}
]
}
}
Параметры
Запрос script_score
поддерживает следующие параметры верхнего уровня.
Параметр | Тип данных | Описание |
---|---|---|
query |
Объект | Запрос, используемый для поиска. Обязательный. |
script |
Объект | Скрипт, используемый для вычисления оценки документов, возвращаемых запросом. Обязательный. |
min_score |
Число с плавающей запятой | Исключает документы с оценкой ниже min_score из результатов. Необязательный. |
boost |
Число с плавающей запятой | Увеличивает оценки документов на заданный множитель. Значения меньше 1.0 уменьшают релевантность, а значения больше 1.0 увеличивают релевантность. По умолчанию 1.0. |
Оценки релевантности, вычисленные запросом script_score
, не могут быть отрицательными.
Настройка вычисления оценки с помощью встроенных функций
Чтобы настроить вычисление оценки, вы можете использовать одну из встроенных функций Painless. Для каждой функции OpenSearch предоставляет один или несколько методов Painless, которые вы можете использовать в контексте оценки скрипта. Вы можете вызывать методы Painless, перечисленные в следующих разделах, напрямую, без использования имени класса или имени экземпляра.
Сатурация
Функция сатурации вычисляет сатурацию как score = value / (value + pivot)
, где value
— это значение поля, а pivot
выбирается так, чтобы оценка была больше 0.5, если value
больше pivot
, и меньше 0.5, если value
меньше pivot
. Оценка находится в диапазоне (0, 1). Чтобы применить функцию сатурации, вызовите следующий метод Painless:
double saturation(double <field-value>, double <pivot>)
ПРИМЕР
Следующий пример запроса ищет текст “neural search” в индексе статей. Он комбинирует оригинальную оценку релевантности документа с значением article_rank
, которое сначала преобразуется с помощью функции сатурации:
GET articles/_search
{
"query": {
"script_score": {
"query": {
"match": { "article_name": "neural search" }
},
"script": {
"source": "_score + saturation(doc['article_rank'].value, 11)"
}
}
}
}
Сигмоид
Аналогично функции сатурации, функция сигмоид вычисляет оценку как score = value^exp / (value^exp + pivot^exp)
, где value
— это значение поля, exp
— это коэффициент масштабирования степени, а pivot
выбирается так, чтобы оценка была больше 0.5, если value
больше pivot
, и меньше 0.5, если value
меньше pivot
. Чтобы применить функцию сигмоид, вызовите следующий метод Painless:
double sigmoid(double <field-value>, double <pivot>, double <exp>)
Пример
Следующий пример запроса ищет текст “neural search” в индексе статей. Он комбинирует оригинальную оценку релевантности документа со значением article_rank
, которое сначала преобразуется с помощью функции сигмоид:
GET articles/_search
{
"query": {
"script_score": {
"query": {
"match": { "article_name": "neural search" }
},
"script": {
"source": "_score + sigmoid(doc['article_rank'].value, 11, 2)"
}
}
}
}
Случайная оценка
Функция случайной оценки генерирует равномерно распределенные случайные оценки в диапазоне [0, 1). Чтобы узнать, как работает эта функция, смотрите раздел “Функция случайной оценки”. Чтобы применить функцию случайной оценки, вызовите один из следующих методов Painless:
double randomScore(int <seed>): Использует внутренние идентификаторы документов Lucene в качестве значений семени.
double randomScore(int <seed>, String <field-name>)
Пример
Следующий запрос использует функцию random_score
с семенем и полем:
GET articles/_search
{
"query": {
"script_score": {
"query": {
"match": { "article_name": "neural search" }
},
"script": {
"source": "randomScore(20, '_seq_no')"
}
}
}
}
Функции затухания
С помощью функций затухания вы можете оценивать результаты на основе близости или недавности. Чтобы узнать больше, смотрите раздел “Функции затухания”. Вы можете вычислять оценки, используя экспоненциальную, гауссову или линейную кривую затухания. Чтобы применить функцию затухания, вызовите один из следующих методов Painless в зависимости от типа поля:
Числовые поля:
double decayNumericGauss(double <origin>, double <scale>, double <offset>, double <decay>, double <field-value>)
double decayNumericExp(double <origin>, double <scale>, double <offset>, double <decay>, double <field-value>)
double decayNumericLinear(double <origin>, double <scale>, double <offset>, double <decay>, double <field-value>)
Геопоинтовые поля:
double decayGeoGauss(String <origin>, String <scale>, String <offset>, double <decay>, GeoPoint <field-value>)
double decayGeoExp(String <origin>, String <scale>, String <offset>, double <decay>, GeoPoint <field-value>)
double decayGeoLinear(String <origin>, String <scale>, String <offset>, double <decay>, GeoPoint <field-value>)
Поля даты:
double decayDateGauss(String <origin>, String <scale>, String <offset>, double <decay>, JodaCompatibleZonedDateTime <field-value>)
double decayDateExp(String <origin>, String <scale>, String <offset>, double <decay>, JodaCompatibleZonedDateTime <field-value>)
double decayDateLinear(String <origin>, String <scale>, String <offset>, double <decay>, JodaCompatibleZonedDateTime <field-value>)
Пример: Числовые поля
Следующий запрос использует функцию экспоненциального затухания на числовом поле:
GET articles/_search
{
"query": {
"script_score": {
"query": {
"match": {
"article_name": "neural search"
}
},
"script": {
"source": "decayNumericExp(params.origin, params.scale, params.offset, params.decay, doc['article_rank'].value)",
"params": {
"origin": 50,
"scale": 20,
"offset": 30,
"decay": 0.5
}
}
}
}
}
Пример: Геопоинтовые поля
Следующий запрос использует функцию гауссового затухания на геопоинтовом поле:
GET hotels/_search
{
"query": {
"script_score": {
"query": {
"match": {
"name": "hotel"
}
},
"script": {
"source": "decayGeoGauss(params.origin, params.scale, params.offset, params.decay, doc['location'].value)",
"params": {
"origin": "40.71,74.00",
"scale": "300ft",
"offset": "200ft",
"decay": 0.25
}
}
}
}
}
Пример: Поля даты
Следующий запрос использует функцию линейного затухания на поле даты:
GET blogs/_search
{
"query": {
"script_score": {
"query": {
"match": {
"name": "opensearch"
}
},
"script": {
"source": "decayDateLinear(params.origin, params.scale, params.offset, params.decay, doc['date_posted'].value)",
"params": {
"origin": "2022-04-24",
"scale": "6d",
"offset": "1d",
"decay": 0.25
}
}
}
}
}
Функции частоты термина
Функции частоты термина предоставляют статистику на уровне термина в источнике скрипта оценки. Вы можете использовать эту статистику для реализации пользовательских алгоритмов извлечения информации и ранжирования, таких как умножение или сложение оценки по популярности во время запроса. Чтобы применить функцию частоты термина, вызовите один из следующих методов Painless:
int termFreq(String <field-name>, String <term>)
: Извлекает частоту термина в поле для конкретного термина.long totalTermFreq(String <field-name>, String <term>)
: Извлекает общую частоту термина в поле для конкретного термина.long sumTotalTermFreq(String <field-name>)
: Извлекает сумму общих частот термина в поле.
Пример
Следующий запрос вычисляет оценку как общую частоту термина для каждого поля в списке полей, умноженную на значение множителя:
GET /demo_index_v1/_search
{
"query": {
"function_score": {
"query": {
"match_all": {}
},
"script_score": {
"script": {
"source": """
for (int x = 0; x < params.fields.length; x++) {
String field = params.fields[x];
if (field != null) {
return params.multiplier * totalTermFreq(field, params.term);
}
}
return params.default_value;
""",
"params": {
"fields": ["title", "description"],
"term": "ai",
"multiplier": 2,
"default_value": 1
}
}
}
}
}
}