Учебник: гибридный поиск с semantic_text
В этом учебнике показано, как выполнять гибридный поиск, объединяя семантический поиск с традиционным полнотекстовым поиском.
При гибридном поиске семантический поиск извлекает результаты, основываясь на значении текста, а полнотекстовый поиск фокусируется на точном соответствии слов. Объединение обоих методов обеспечивает более релевантные результаты, особенно в тех случаях, когда использование одного подхода может оказаться недостаточным.
Рекомендуемый способ использования гибридного поиска в Elastic Stack — выполнение процесса semantic_text. В этом руководстве для демонстрации используется служба elasticsearch, но вы можете использовать любую службу и поддерживаемые ею модели, предлагаемые API Inference.
Создайте отображение индекса
Индекс назначения будет содержать как вложения для семантического поиска, так и исходное текстовое поле для полнотекстового поиска. Такая структура позволяет объединить семантический и полнотекстовый поиск.
PUT semantic-embeddings
{
"mappings": {
"properties": {
"semantic_text": {
"type": "semantic_text"
},
"content": {
"type": "text",
"copy_to": "semantic_text"
}
}
}
} | Имя поля, содержащего сгенерированные вложения для семантического поиска. | |
| Имя поля, содержащего исходный текст для лексического поиска. | |
| Текстовые данные, хранящиеся в поле |
Если вы хотите выполнить поиск в индексах, заполненных веб-бот-фермерами или коннекторами, вам нужно обновить отображения индексов для этих индексов, включив поле semantic_text. После обновления отображения вам необходимо выполнить полный веб-скрейпинг или синхронизацию коннектора. Это гарантирует, что все существующие документы будут повторно обработаны и обновлены с новыми семантическими вложениями, что позволит выполнить гибридный поиск по обновлённым данным.
Загрузка данных
На этом шаге вы загружаете данные, которые впоследствии используете для создания вложений.
Используйте набор данных msmarco-passagetest2019-top1000, который является подмножеством набора данных MS MARCO Passage Ranking. Он состоит из 200 запросов, каждый из которых сопровождается списком релевантных текстовых фрагментов. Все уникальные фрагменты вместе с их идентификаторами были извлечены из этого набора данных и объединены в файл tsv.
Загрузите файл и загрузите его в свой кластер с помощью Визуализатора данных в интерфейсе Machine Learning. После анализа данных нажмите Переопределить настройки. В разделе Изменить имена полей присвойте id первому столбцу и content второму. Нажмите Применить, затем Импортировать. Назовите индекс test-data и нажмите Импортировать. После завершения загрузки вы увидите индекс под названием test-data с 182 469 документами.
Переиндексация данных для гибридного поиска
Переиндексируйте данные из индекса test-data в индекс semantic-embeddings. Данные из поля content исходного индекса копируются в поле content целевого индекса. Параметр copy_to, заданный при создании отображения индекса, гарантирует копирование содержимого в поле semantic_text. Данные обрабатываются конечной точкой вывода при поступлении для генерации вложений.
На этом шаге для моделирования поступления данных используется API переиндексации. Если вы работаете с данными, которые уже были проиндексированы, а не используете test-data, переиндексация всё равно требуется, чтобы данные были обработаны конечной точкой вывода и были сгенерированы необходимые вложения.
resp = client.reindex(
wait_for_completion=False,
source={
"index": "test-data",
"size": 10
},
dest={
"index": "semantic-embeddings"
},
)
print(resp) const response = await client.reindex({
wait_for_completion: "false",
source: {
index: "test-data",
size: 10,
},
dest: {
index: "semantic-embeddings",
},
});
console.log(response); POST _reindex?wait_for_completion=false
{
"source": {
"index": "test-data",
"size": 10
},
"dest": {
"index": "semantic-embeddings"
}
} | Размер пакета по умолчанию для переиндексации составляет 1000. Уменьшение размера до меньшего числа ускоряет процесс обновления переиндексации, что позволяет вам внимательно следить за процессом и быстро обнаруживать ошибки. |
Вызов возвращает идентификатор задачи для отслеживания прогресса:
resp = client.tasks.get(
task_id="<task_id>",
)
print(resp) const response = await client.tasks.get({
task_id: "<task_id>",
});
console.log(response); GET _tasks/<task_id>
Переиндексация больших наборов данных может занять много времени. Вы можете протестировать этот рабочий процесс, используя только подмножество набора данных.
Для отмены процесса переиндексации и генерации вложений для подмножества, которое было переиндексировано:
resp = client.tasks.cancel(
task_id="<task_id>",
)
print(resp) const response = await client.tasks.cancel({
task_id: "<task_id>",
});
console.log(response); POST _tasks/<task_id>/_cancel
Выполнение гибридного поиска
После переиндексации данных в индекс semantic-embeddings можно выполнить гибридный поиск, используя взаимное ранжирование слияния (RRF). RRF — это техника, объединяющая ранжирование из семантических и лексических запросов, придавая больший вес результатам, которые высоко ранжируются в любом из поисков. Это гарантирует сбалансированность и релевантность конечных результатов.
GET semantic-embeddings/_search
{
"retriever": {
"rrf": {
"retrievers": [
{
"standard": {
"query": {
"match": {
"content": "How to avoid muscle soreness while running?"
}
}
}
},
{
"standard": {
"query": {
"semantic": {
"field": "semantic_text",
"query": "How to avoid muscle soreness while running?"
}
}
}
}
]
}
}
} | Первый | |
| Лексический поиск выполняется в поле | |
| Второй | |
| Для выполнения семантического поиска используется поле |
После выполнения гибридного поиска запрос вернёт 10 лучших документов, соответствующих как семантическим, так и лексическим критериям поиска. Результаты включают подробную информацию о каждом документе:
{
"took": 107,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 473,
"relation": "eq"
},
"max_score": null,
"hits": [
{
"_index": "semantic-embeddings",
"_id": "wv65epIBEMBRnhfTsOFM",
"_score": 0.032786883,
"_rank": 1,
"_source": {
"semantic_text": {
"inference": {
"inference_id": "my-elser-endpoint",
"model_settings": {
"task_type": "sparse_embedding"
},
"chunks": [
{
"text": "What so many out there do not realize is the importance of what you do after you work out. You may have done the majority of the work, but how you treat your body in the minutes and hours after you exercise has a direct effect on muscle soreness, muscle strength and growth, and staying hydrated. Cool Down. After your last exercise, your workout is not over. The first thing you need to do is cool down. Even if running was all that you did, you still should do light cardio for a few minutes. This brings your heart rate down at a slow and steady pace, which helps you avoid feeling sick after a workout.",
"embeddings": {
"exercise": 1.571044,
"after": 1.3603843,
"sick": 1.3281639,
"cool": 1.3227621,
"muscle": 1.2645415,
"sore": 1.2561599,
"cooling": 1.2335974,
"running": 1.1750668,
"hours": 1.1104802,
"out": 1.0991782,
"##io": 1.0794281,
"last": 1.0474665,
(...)
}
}
]
}
},
"id": 8408852,
"content": "What so many out there do not realize is the importance of (...)"
}
}
]
}
}
© 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/semantic-text-hybrid-search.html