Spec-Zone.ru › Elasticsearch 8
›Elasticsearch Guide [8.17] ›Query DSL ›Запросы на основе векторов

Запрос на основе разреженных векторов

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

  • Использование модели обработки естественного языка для преобразования текста запроса в список пар «токен-вес»
  • Передача предварительно рассчитанных пар «токен-вес» в качестве векторов запроса

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

Например, хранимый вектор {"feature_0": 0.12, "feature_1": 1.2, "feature_2": 3.0} с вектором запроса {"feature_0": 2.5, "feature_2": 0.2} получил бы рейтинг документа _score = 0.12*2.5 + 3.0*0.2 = 0.9

Пример запроса с использованием модели обработки естественного языка

resp = client.search(
    query={
        "sparse_vector": {
            "field": "ml.tokens",
            "inference_id": "the inference ID to produce the token weights",
            "query": "the query string"
        }
    },
)
print(resp)
const response = await client.search({
  query: {
    sparse_vector: {
      field: "ml.tokens",
      inference_id: "the inference ID to produce the token weights",
      query: "the query string",
    },
  },
});
console.log(response);
GET _search
{
   "query":{
      "sparse_vector": {
        "field": "ml.tokens",
        "inference_id": "the inference ID to produce the token weights",
        "query": "the query string"
      }
   }
}

Пример запроса с использованием предварительно вычисленных векторов

resp = client.search(
    query={
        "sparse_vector": {
            "field": "ml.tokens",
            "query_vector": {
                "token1": 0.5,
                "token2": 0.3,
                "token3": 0.2
            }
        }
    },
)
print(resp)
const response = await client.search({
  query: {
    sparse_vector: {
      field: "ml.tokens",
      query_vector: {
        token1: 0.5,
        token2: 0.3,
        token3: 0.2,
      },
    },
  },
});
console.log(response);
GET _search
{
   "query":{
      "sparse_vector": {
        "field": "ml.tokens",
        "query_vector": { "token1": 0.5, "token2": 0.3, "token3": 0.2 }
      }
   }
}

Параметры верхнего уровня для sparse_vector

field
(Обязательно, строка) Название поля, содержащего пары «токен-вес», по которым выполняется поиск.
inference_id
(Необязательно, строка) Идентификатор вывода для преобразования текста запроса в пары «токен-вес». Он должен совпадать с идентификатором вывода, который использовался для создания токенов из входного текста. Разрешено только одно из значений inference_id и query_vector. Если указан inference_id, то должен быть указан и query. Вы можете сослаться на deployment_id развертывания обученной модели машинного обучения в качестве inference_id. Например, если вы скачиваете и развертываете модель ELSER в пользовательском интерфейсе Kibana «Обученные модели машинного обучения», вы можете использовать deployment_id этого развертывания в качестве inference_id.
query
(Необязательно, строка) Текст запроса, который вы хотите использовать для поиска. Если указан inference_id, то должен быть указан и query. Если указан query_vector, то query не должен быть указан.
query_vector
(Необязательно, словарь) Словарь пар «токен-вес», представляющих предварительно вычисленный вектор запроса для поиска. Поиск с помощью этого вектора запроса обойдет дополнительный вывод. Разрешено только одно из значений inference_id и query_vector.
prune
(Необязательно, булево) [preview] Эта функция находится на стадии технического предварительного просмотра и может быть изменена или удалена в будущих выпусках. Elastic будет работать над устранением любых проблем, но функции технического предварительного просмотра не подлежат SLA поддержки официальных функций GA. Выполнять ли обрезку, исключая несущественные токены из запроса для повышения производительности запроса. Если prune имеет значение true, но pruning_config не указан, обрезка произойдет, но будут использоваться значения по умолчанию. По умолчанию: false.
pruning_config

(Необязательно, объект) [preview] Эта функция находится на стадии технического предварительного просмотра и может быть изменена или удалена в будущих выпусках. Elastic будет работать над устранением любых проблем, но функции технического предварительного просмотра не подлежат SLA поддержки официальных функций GA. Необязательная конфигурация обрезки. При включении это позволит исключить несущественные токены из запроса для повышения производительности запроса. Используется только в том случае, если prune установлено в true. Если prune установлено в true, но pruning_config не указано, будут использоваться значения по умолчанию.

Параметры для pruning_config:

tokens_freq_ratio_threshold
(Необязательно, целое число) [preview] Эта функция находится на стадии технического предварительного просмотра и может быть изменена или удалена в будущих выпусках. Elastic будет работать над устранением любых проблем, но функции технического предварительного просмотра не подлежат SLA поддержки официальных функций GA. Токены, частота которых превышает tokens_freq_ratio_threshold раз среднюю частоту всех токенов в указанном поле, считаются выбросами и подлежат обрезке. Это значение должно быть между 1 и 100. По умолчанию: 5.
tokens_weight_threshold
(Необязательно, число с плавающей запятой) [preview] Эта функция находится на стадии технического предварительного просмотра и может быть изменена или удалена в будущих выпусках. Elastic будет работать над устранением любых проблем, но функции технического предварительного просмотра не подлежат SLA поддержки официальных функций GA. Токены, вес которых меньше tokens_weight_threshold, считаются несущественными и подлежат обрезке. Это значение должно быть между 0 и 1. По умолчанию: 0.4.
only_score_pruned_tokens
(Необязательно, булево) [preview] Эта функция находится на стадии технического предварительного просмотра и может быть изменена или удалена в будущих выпусках. Elastic будет работать над устранением любых проблем, но функции технического предварительного просмотра не подлежат SLA поддержки официальных функций GA. Если true, мы вводим только обрезки токенов в оценку и отбрасываем необрезанные токены. Сильно рекомендуется установить это в false для основного запроса, но это можно установить в true для запроса переоценки, чтобы получить более релевантные результаты. По умолчанию: false.

Значения по умолчанию для tokens_freq_ratio_threshold и tokens_weight_threshold были выбраны на основе тестов с использованием ELSERv2, которые обеспечивали наилучшие результаты.

Пример запроса ELSER

Ниже приведен пример запроса sparse_vector, который ссылается на модель ELSER для выполнения семантического поиска. Для более подробного описания того, как выполнить семантический поиск с помощью ELSER и запроса sparse_vector, см. данный учебник.

resp = client.search(
    index="my-index",
    query={
        "sparse_vector": {
            "field": "ml.tokens",
            "inference_id": "my-elser-model",
            "query": "How is the weather in Jamaica?"
        }
    },
)
print(resp)
const response = await client.search({
  index: "my-index",
  query: {
    sparse_vector: {
      field: "ml.tokens",
      inference_id: "my-elser-model",
      query: "How is the weather in Jamaica?",
    },
  },
});
console.log(response);
GET my-index/_search
{
   "query":{
      "sparse_vector": {
         "field": "ml.tokens",
         "inference_id": "my-elser-model",
         "query": "How is the weather in Jamaica?"
      }
   }
}

Несколько запросов sparse_vector могут быть объединены друг с другом или с другими типами запросов. Это можно сделать, обернув их в булевы запросы и используя линейное усиление:

resp = client.search(
    index="my-index",
    query={
        "bool": {
            "should": [
                {
                    "sparse_vector": {
                        "field": "ml.inference.title_expanded.predicted_value",
                        "inference_id": "my-elser-model",
                        "query": "How is the weather in Jamaica?",
                        "boost": 1
                    }
                },
                {
                    "sparse_vector": {
                        "field": "ml.inference.description_expanded.predicted_value",
                        "inference_id": "my-elser-model",
                        "query": "How is the weather in Jamaica?",
                        "boost": 1
                    }
                },
                {
                    "multi_match": {
                        "query": "How is the weather in Jamaica?",
                        "fields": [
                            "title",
                            "description"
                        ],
                        "boost": 4
                    }
                }
            ]
        }
    },
)
print(resp)
const response = await client.search({
  index: "my-index",
  query: {
    bool: {
      should: [
        {
          sparse_vector: {
            field: "ml.inference.title_expanded.predicted_value",
            inference_id: "my-elser-model",
            query: "How is the weather in Jamaica?",
            boost: 1,
          },
        },
        {
          sparse_vector: {
            field: "ml.inference.description_expanded.predicted_value",
            inference_id: "my-elser-model",
            query: "How is the weather in Jamaica?",
            boost: 1,
          },
        },
        {
          multi_match: {
            query: "How is the weather in Jamaica?",
            fields: ["title", "description"],
            boost: 4,
          },
        },
      ],
    },
  },
});
console.log(response);
GET my-index/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "sparse_vector": {
            "field": "ml.inference.title_expanded.predicted_value",
            "inference_id": "my-elser-model",
            "query": "How is the weather in Jamaica?",
            "boost": 1
          }
        },
        {
          "sparse_vector": {
            "field": "ml.inference.description_expanded.predicted_value",
            "inference_id": "my-elser-model",
            "query": "How is the weather in Jamaica?",
            "boost": 1
          }
        },
        {
          "multi_match": {
            "query": "How is the weather in Jamaica?",
            "fields": [
              "title",
              "description"
            ],
            "boost": 4
          }
        }
      ]
    }
  }
}

Это также можно сделать с помощью обратного ранжирования (RRF) с помощью rrf ретривера с несколькими standard ретриверами.

resp = client.search(
    index="my-index",
    retriever={
        "rrf": {
            "retrievers": [
                {
                    "standard": {
                        "query": {
                            "multi_match": {
                                "query": "How is the weather in Jamaica?",
                                "fields": [
                                    "title",
                                    "description"
                                ]
                            }
                        }
                    }
                },
                {
                    "standard": {
                        "query": {
                            "sparse_vector": {
                                "field": "ml.inference.title_expanded.predicted_value",
                                "inference_id": "my-elser-model",
                                "query": "How is the weather in Jamaica?",
                                "boost": 1
                            }
                        }
                    }
                },
                {
                    "standard": {
                        "query": {
                            "sparse_vector": {
                                "field": "ml.inference.description_expanded.predicted_value",
                                "inference_id": "my-elser-model",
                                "query": "How is the weather in Jamaica?",
                                "boost": 1
                            }
                        }
                    }
                }
            ],
            "window_size": 10,
            "rank_constant": 20
        }
    },
)
print(resp)
const response = await client.search({
  index: "my-index",
  retriever: {
    rrf: {
      retrievers: [
        {
          standard: {
            query: {
              multi_match: {
                query: "How is the weather in Jamaica?",
                fields: ["title", "description"],
              },
            },
          },
        },
        {
          standard: {
            query: {
              sparse_vector: {
                field: "ml.inference.title_expanded.predicted_value",
                inference_id: "my-elser-model",
                query: "How is the weather in Jamaica?",
                boost: 1,
              },
            },
          },
        },
        {
          standard: {
            query: {
              sparse_vector: {
                field: "ml.inference.description_expanded.predicted_value",
                inference_id: "my-elser-model",
                query: "How is the weather in Jamaica?",
                boost: 1,
              },
            },
          },
        },
      ],
      window_size: 10,
      rank_constant: 20,
    },
  },
});
console.log(response);
GET my-index/_search
{
  "retriever": {
    "rrf": {
      "retrievers": [
        {
          "standard": {
            "query": {
              "multi_match": {
                "query": "How is the weather in Jamaica?",
                "fields": [
                  "title",
                  "description"
                ]
              }
            }
          }
        },
        {
          "standard": {
            "query": {
              "sparse_vector": {
                "field": "ml.inference.title_expanded.predicted_value",
                "inference_id": "my-elser-model",
                "query": "How is the weather in Jamaica?",
                "boost": 1
              }
            }
          }
        },
        {
          "standard": {
            "query": {
              "sparse_vector": {
                "field": "ml.inference.description_expanded.predicted_value",
                "inference_id": "my-elser-model",
                "query": "How is the weather in Jamaica?",
                "boost": 1
              }
            }
          }
        }
      ],
      "window_size": 10,
      "rank_constant": 20
    }
  }
}

Пример запроса ELSER с конфигурацией обрезки и переоценкой

Ниже представлено расширение приведенного выше примера, которое добавляет [preview] Эта функция находится на стадии технического предварительного просмотра и может быть изменена или удалена в будущих выпусках. Elastic будет работать над устранением любых проблем, но функции технического предварительного просмотра не подлежат SLA поддержки официальных функций GA. конфигурацию обрезки к запросу sparse_vector. Конфигурация обрезки идентифицирует несущественные токены для обрезки из запроса, чтобы повысить производительность запроса.

Обрезка токенов происходит на уровне фрагмента. Хотя это должно привести к тому, что одни и те же токены будут помечены как несущественные на всех фрагментах, это не гарантируется на основе состава каждого фрагмента. Поэтому, если вы выполняете sparse_vector с pruning_config на индексе с несколькими фрагментами, мы настоятельно рекомендуем добавить функцию переоценки отфильтрованных результатов поиска с токенами, которые изначально были обрезанны из запроса. Это поможет смягчить любые несоответствия на уровне фрагментов с обрезанными токенами и обеспечить более высокую релевантность в целом.

resp = client.search(
    index="my-index",
    query={
        "sparse_vector": {
            "field": "ml.tokens",
            "inference_id": "my-elser-model",
            "query": "How is the weather in Jamaica?",
            "prune": True,
            "pruning_config": {
                "tokens_freq_ratio_threshold": 5,
                "tokens_weight_threshold": 0.4,
                "only_score_pruned_tokens": False
            }
        }
    },
    rescore={
        "window_size": 100,
        "query": {
            "rescore_query": {
                "sparse_vector": {
                    "field": "ml.tokens",
                    "inference_id": "my-elser-model",
                    "query": "How is the weather in Jamaica?",
                    "prune": True,
                    "pruning_config": {
                        "tokens_freq_ratio_threshold": 5,
                        "tokens_weight_threshold": 0.4,
                        "only_score_pruned_tokens": True
                    }
                }
            }
        }
    },
)
print(resp)
const response = await client.search({
  index: "my-index",
  query: {
    sparse_vector: {
      field: "ml.tokens",
      inference_id: "my-elser-model",
      query: "How is the weather in Jamaica?",
      prune: true,
      pruning_config: {
        tokens_freq_ratio_threshold: 5,
        tokens_weight_threshold: 0.4,
        only_score_pruned_tokens: false,
      },
    },
  },
  rescore: {
    window_size: 100,
    query: {
      rescore_query: {
        sparse_vector: {
          field: "ml.tokens",
          inference_id: "my-elser-model",
          query: "How is the weather in Jamaica?",
          prune: true,
          pruning_config: {
            tokens_freq_ratio_threshold: 5,
            tokens_weight_threshold: 0.4,
            only_score_pruned_tokens: true,
          },
        },
      },
    },
  },
});
console.log(response);
GET my-index/_search
{
   "query":{
      "sparse_vector":{
         "field": "ml.tokens",
         "inference_id": "my-elser-model",
         "query":"How is the weather in Jamaica?",
         "prune": true,
         "pruning_config": {
           "tokens_freq_ratio_threshold": 5,
           "tokens_weight_threshold": 0.4,
           "only_score_pruned_tokens": false
         }
      }
   },
   "rescore": {
      "window_size": 100,
      "query": {
         "rescore_query": {
            "sparse_vector": {
               "field": "ml.tokens",
               "inference_id": "my-elser-model",
               "query": "How is the weather in Jamaica?",
               "prune": true,
               "pruning_config": {
                   "tokens_freq_ratio_threshold": 5,
                   "tokens_weight_threshold": 0.4,
                   "only_score_pruned_tokens": true
               }
            }
         }
      }
   }
}

При выполнении поиска по нескольким кластерам вывод выполняется в локальном кластере.

© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/query-dsl-sparse-vector-query.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API