Тип поля Percolator
Тип поля percolator парсит структуру JSON в родной запрос и сохраняет этот запрос, чтобы запрос percolate мог использовать его для сопоставления предоставленных документов.
Любое поле, содержащее JSON-объект, можно настроить как поле percolator. У типа поля percolator нет настроек. Достаточно настроить тип поля percolator, чтобы указать Elasticsearch на обработку поля как запроса.
Если следующая конфигурация отображения настраивает тип поля percolator для поля query:
PUT my-index-000001
{
"mappings": {
"properties": {
"query": {
"type": "percolator"
},
"field": {
"type": "text"
}
}
}
} Тогда вы можете индексировать запрос:
PUT my-index-000001/_doc/match_value
{
"query": {
"match": {
"field": "value"
}
}
} Поля, на которые ссылается запрос percolator, должны уже существовать в отображении, связанном с индексом, используемым для перколяции. Чтобы убедиться, что эти поля существуют, добавьте или обновите отображение с помощью API создания индекса или обновления отображения.
Переиндексация ваших запросов percolator
Переиндексация запросов percolator иногда необходима, чтобы воспользоваться улучшениями типа поля percolator в новых выпусках.
Переиндексацию запросов percolator можно выполнить с помощью API переиндексации. Давайте рассмотрим следующий индекс с типом поля percolator:
PUT index
{
"mappings": {
"properties": {
"query" : {
"type" : "percolator"
},
"body" : {
"type": "text"
}
}
}
}
POST _aliases
{
"actions": [
{
"add": {
"index": "index",
"alias": "queries"
}
}
]
}
PUT queries/_doc/1?refresh
{
"query" : {
"match" : {
"body" : "quick brown fox"
}
}
} | Рекомендуется всегда определять псевдоним для вашего индекса, чтобы в случае переиндексации системам/приложениям не нужно было изменять способ получения запросов percolator, которые теперь находятся в другом индексе. |
Предположим, что вы переходите на новую главную версию, и для того, чтобы новая версия Elasticsearch по-прежнему могла читать ваши запросы, вам необходимо переиндексировать ваши запросы в новый индекс в текущей версии Elasticsearch:
PUT new_index
{
"mappings": {
"properties": {
"query" : {
"type" : "percolator"
},
"body" : {
"type": "text"
}
}
}
}
POST /_reindex?refresh
{
"source": {
"index": "index"
},
"dest": {
"index": "new_index"
}
}
POST _aliases
{
"actions": [
{
"remove": {
"index" : "index",
"alias": "queries"
}
},
{
"add": {
"index": "new_index",
"alias": "queries"
}
}
]
} | Если у вас есть псевдоним, не забудьте направить его на новый индекс. |
Выполнение запроса percolate через псевдоним queries:
GET /queries/_search
{
"query": {
"percolate" : {
"field" : "query",
"document" : {
"body" : "fox jumps over the lazy dog"
}
}
}
} теперь возвращает совпадения из нового индекса:
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped" : 0,
"failed": 0
},
"hits": {
"total" : {
"value": 1,
"relation": "eq"
},
"max_score": 0.13076457,
"hits": [
{
"_index": "new_index",
"_type": "_doc",
"_id": "1",
"_score": 0.13076457,
"_source": {
"query": {
"match": {
"body": "quick brown fox"
}
}
},
"fields" : {
"_percolator_document_slot" : [0]
}
}
]
}
} | Результат поиска по запросу percolator теперь представлен из нового индекса. |
Оптимизация анализа текста во время выполнения запроса
Когда percolator проверяет соответствие кандидата percolator, он будет парсить, выполнять анализ текста во время выполнения запроса и фактически выполнять запрос percolator на документе, который перколируется. Это выполняется для каждого кандидата и каждый раз, когда выполняется запрос percolate. Если ваш анализ текста во время выполнения запроса относительно дорогостоящая часть анализа запроса, то анализ текста может стать доминирующим фактором, на котором тратится время при перколяции. Эта издержки при разборе запроса могут стать заметными, когда percolator заканчивает проверку многих соответствий кандидата percolator.
Чтобы избежать наиболее дорогостоящей части анализа текста во время перколяции, можно выполнить дорогостоящую часть анализа текста при индексировании запроса percolator. Это требует использования двух разных анализаторов. Первый анализатор выполняет необходимый анализ текста (дорогостоящую часть). Второй анализатор (обычно пробел) просто разбивает сгенерированные токены, которые сгенерировал первый анализатор. Затем перед индексированием запроса percolator следует использовать API analyze для анализа текста запроса с помощью более дорогостоящего анализатора. Результат API analyze, токены, следует использовать для замены исходного текста запроса в запросе percolator. Важно, чтобы запрос был настроен на переопределение анализатора из отображения и использовал только второй анализатор. Большинство текстовых запросов поддерживают опцию analyzer (match, query_string, simple_query_string). Используя этот подход, дорогостоящий анализ текста выполняется один раз вместо многих.
Давайте продемонстрируем этот рабочий процесс на упрощенном примере.
Предположим, что мы хотим индексировать следующий запрос percolator:
{
"query" : {
"match" : {
"body" : {
"query" : "missing bicycles"
}
}
}
} с этими настройками и отображением:
PUT /test_index
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer" : {
"tokenizer": "standard",
"filter" : ["lowercase", "porter_stem"]
}
}
}
},
"mappings": {
"properties": {
"query" : {
"type": "percolator"
},
"body" : {
"type": "text",
"analyzer": "my_analyzer"
}
}
}
} | Для целей этого примера этот анализатор считается дорогостоящим. |
Сначала нам нужно использовать API analyze для выполнения анализа текста перед индексированием:
POST /test_index/_analyze
{
"analyzer" : "my_analyzer",
"text" : "missing bicycles"
} Это приводит к следующему ответу:
{
"tokens": [
{
"token": "miss",
"start_offset": 0,
"end_offset": 7,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "bicycl",
"start_offset": 8,
"end_offset": 16,
"type": "<ALPHANUM>",
"position": 1
}
]
} Все токены в возвращенном порядке должны заменить текст запроса в запросе percolator:
PUT /test_index/_doc/1?refresh
{
"query" : {
"match" : {
"body" : {
"query" : "miss bicycl",
"analyzer" : "whitespace"
}
}
}
} | Важно выбрать анализатор пробелов здесь, иначе будет использован анализатор, определенный в отображении, что сведёт на нет цель использования этого рабочего процесса. Обратите внимание, что |
API analyze перед индексированием потока percolator должен выполняться для каждого запроса percolator.
Во время перколяции ничего не меняется, и запрос percolate можно определить обычно:
GET /test_index/_search
{
"query": {
"percolate" : {
"field" : "query",
"document" : {
"body" : "Bycicles are missing"
}
}
}
} Это приводит к ответу такого вида:
{
"took": 6,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped" : 0,
"failed": 0
},
"hits": {
"total" : {
"value": 1,
"relation": "eq"
},
"max_score": 0.13076457,
"hits": [
{
"_index": "test_index",
"_type": "_doc",
"_id": "1",
"_score": 0.13076457,
"_source": {
"query": {
"match": {
"body": {
"query": "miss bicycl",
"analyzer": "whitespace"
}
}
}
},
"fields" : {
"_percolator_document_slot" : [0]
}
}
]
}
} Оптимизация запросов с подстановочными знаками
Запросы с подстановочными знаками сложнее, чем другие запросы для percolator, особенно если выражения с подстановочными знаками большие.
В случае запросов wildcard с префиксными подстановочными знаками или просто запросом prefix можно использовать токен-фильтр edge_ngram для замены этих запросов обычным запросом term на поле, где настроен токен-фильтр edge_ngram.
Создание индекса с пользовательскими настройками анализа:
PUT my_queries1
{
"settings": {
"analysis": {
"analyzer": {
"wildcard_prefix": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"wildcard_edge_ngram"
]
}
},
"filter": {
"wildcard_edge_ngram": {
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 32
}
}
}
},
"mappings": {
"properties": {
"query": {
"type": "percolator"
},
"my_field": {
"type": "text",
"fields": {
"prefix": {
"type": "text",
"analyzer": "wildcard_prefix",
"search_analyzer": "standard"
}
}
}
}
}
} | Анализатор, генерирующий префиксные токены, используемые во время индексирования. | |
| Увеличьте настройку | |
| Этот многопольный должен использоваться для поиска по префиксу с запросом |
Затем вместо индексирования следующего запроса:
{
"query": {
"wildcard": {
"my_field": "abc*"
}
}
} должен индексироваться следующий запрос:
PUT /my_queries1/_doc/1?refresh
{
"query": {
"term": {
"my_field.prefix": "abc"
}
}
} Таким образом, второй запрос может обрабатываться более эффективно, чем первый.
Следующий запрос поиска будет соответствовать ранее индексированному запросу percolator:
GET /my_queries1/_search
{
"query": {
"percolate": {
"field": "query",
"document": {
"my_field": "abcd"
}
}
}
} {
"took": 6,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total" : {
"value": 1,
"relation": "eq"
},
"max_score": 0.18864399,
"hits": [
{
"_index": "my_queries1",
"_type": "_doc",
"_id": "1",
"_score": 0.18864399,
"_source": {
"query": {
"term": {
"my_field.prefix": "abc"
}
}
},
"fields": {
"_percolator_document_slot": [
0
]
}
}
]
}
} Та же техника может быть использована для ускорения поиска по суффиксным подстановочным знакам. Используя токен-фильтр reverse перед токен-фильтром edge_ngram.
PUT my_queries2
{
"settings": {
"analysis": {
"analyzer": {
"wildcard_suffix": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"reverse",
"wildcard_edge_ngram"
]
},
"wildcard_suffix_search_time": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"reverse"
]
}
},
"filter": {
"wildcard_edge_ngram": {
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 32
}
}
}
},
"mappings": {
"properties": {
"query": {
"type": "percolator"
},
"my_field": {
"type": "text",
"fields": {
"suffix": {
"type": "text",
"analyzer": "wildcard_suffix",
"search_analyzer": "wildcard_suffix_search_time"
}
}
}
}
}
} | Необходим пользовательский анализатор и во время поиска, так как в противном случае термины запроса не будут перевернуты и не будут совпадать с сохраненными суффиксными токенами. |
Затем вместо индексирования следующего запроса:
{
"query": {
"wildcard": {
"my_field": "*xyz"
}
}
} должен индексироваться следующий запрос:
PUT /my_queries2/_doc/2?refresh
{
"query": {
"match": {
"my_field.suffix": "xyz"
}
}
} | Следует использовать запрос |
Следующий запрос поиска будет соответствовать ранее индексированному запросу percolator:
GET /my_queries2/_search
{
"query": {
"percolate": {
"field": "query",
"document": {
"my_field": "wxyz"
}
}
}
} Индекс percolator
Запросы percolator могут быть добавлены в любой индекс. Вместо добавления запросов percolator в индекс, в котором находятся данные, эти запросы также могут быть добавлены в отдельный индекс. Преимущество этого заключается в том, что у этого специализированного индекса percolator могут быть свои настройки индекса (например, количество первичных и реплицированных фрагментов). Если вы выберете отдельный индекс percolator, вам нужно убедиться, что отображения из обычного индекса также доступны в индексе percolator. В противном случае запросы percolator могут быть неверно обработаны.
Принудительная обработка полей без отображения как строк
В некоторых случаях неизвестно, какие запросы percolator будут зарегистрированы, и если для полей, на которые ссылаются запросы percolator, нет отображения поля, то добавление запроса percolator завершается неудачей. Это означает, что необходимо обновить отображение, чтобы поле имело соответствующие настройки, и затем можно добавить запрос percolator. Но иногда достаточно, если все поля без отображения обрабатываются так, как если бы они были текстовыми полями по умолчанию. В этих случаях можно настроить настройку index.percolator.map_unmapped_fields_as_text на true (по умолчанию false), и тогда, если поле, указанное в запросе percolator, не существует, оно будет обрабатываться как текстовое поле по умолчанию, чтобы добавление запроса percolator не завершилось ошибкой.
Ограничения
Родитель/потомок
Поскольку запрос percolate обрабатывает один документ за раз, он не поддерживает запросы и фильтры, которые выполняются по отношению к дочерним документам, таким как has_child и has_parent.
Получение запросов
Существует ряд запросов, которые извлекают данные через вызов get во время парсинга запроса. Например, запрос terms при использовании поиска по терминам, запрос template при использовании индексированных скриптов и запрос geo_shape при использовании предварительно индексированных форм. Когда эти запросы индексируются типом поля percolator, вызов get выполняется один раз. Таким образом, каждый раз, когда запрос percolator оценивает эти запросы, будут использоваться извлеченные термины, формы и т.д., как они были на момент индексации. Важно отметить, что извлечение терминов, которое выполняют эти запросы, происходит каждый раз, когда запрос percolator индексируется как на первичных, так и на реплицированных фрагментах, поэтому термины, которые фактически индексируются, могут отличаться между копиями фрагментов, если исходный индекс изменился во время индексирования.
Запрос скрипта
Скрипт внутри запроса script может обращаться только к полям doc values. Запрос percolate индексирует предоставленный документ в индекс в оперативной памяти. Этот индекс в оперативной памяти не поддерживает хранимые поля, и из-за этого поле _source и другие хранимые поля не хранятся. Вот почему в запросе script поля _source и другие хранимые поля недоступны.
Псевдонимы полей
Запросы percolator, содержащие псевдонимы полей, могут не всегда вести себя ожидаемым образом. В частности, если зарегистрирован запрос percolator, который содержит псевдоним поля, а затем этот псевдоним обновляется в отображениях, чтобы ссылаться на другое поле, хранимый запрос по-прежнему будет ссылаться на исходное целевое поле. Для отслеживания изменения псевдонима поля запрос percolator необходимо явно переиндексировать.
© 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/7.17/percolator.html