Использование constant_keyword для ускорения фильтрации
Существует общее правило, что стоимость фильтра в основном зависит от количества совпавших документов. Представьте себе индекс, содержащий велосипеды. Есть большое количество велосипедов, и многие поиски выполняют фильтр по cycle_type: bicycle. Этот очень распространённый фильтр, к сожалению, также очень дорогостоящий, так как он совпадает с большинством документов. Есть простой способ избежать выполнения этого фильтра: переместить велосипеды в отдельный индекс и фильтровать велосипеды, выполняя поиск в этом индексе вместо добавления фильтра к запросу.
К сожалению, это может усложнить логику на стороне клиента, где constant_keyword помогает. Путем сопоставления cycle_type как constant_keyword со значением bicycle в индексе, содержащем велосипеды, клиенты могут продолжать выполнять те же самые запросы, что и раньше, на монолитном индексе, и Elasticsearch сделает нужное на индексе велосипедов, проигнорировав фильтры по cycle_type, если значение равно bicycle, и не вернув совпадений в противном случае.
Вот как могут выглядеть отображения:
PUT bicycles
{
"mappings": {
"properties": {
"cycle_type": {
"type": "constant_keyword",
"value": "bicycle"
},
"name": {
"type": "text"
}
}
}
}
PUT other_cycles
{
"mappings": {
"properties": {
"cycle_type": {
"type": "keyword"
},
"name": {
"type": "text"
}
}
}
} Мы разделяем наш индекс на две части: одну, которая будет содержать только велосипеды, и другую, которая содержит другие виды велосипедов: односкоростные, трехскоростные и т.д. Затем при поиске нам нужно выполнить поиск в обоих индексах, но нам не нужно изменять запросы.
GET bicycles,other_cycles/_search
{
"query": {
"bool": {
"must": {
"match": {
"description": "dutch"
}
},
"filter": {
"term": {
"cycle_type": "bicycle"
}
}
}
}
} В индексе bicycles Elasticsearch просто проигнорирует фильтр cycle_type и перепишет запрос поиска на следующий:
GET bicycles,other_cycles/_search
{
"query": {
"match": {
"description": "dutch"
}
}
} В индексе other_cycles Elasticsearch быстро определит, что bicycle не существует в словаре терминов поля cycle_type, и вернёт ответ поиска без совпадений.
Это эффективный способ удешевить запросы, поместив общие значения в отдельный индекс. Эту идею также можно комбинировать для нескольких полей: например, если вы отслеживаете цвет каждого велосипеда, и ваш индекс bicycles в итоге содержит большинство чёрных велосипедов, вы можете разделить его на индексы bicycles-black и bicycles-other-colors.
constant_keyword не строго обязателен для этой оптимизации: также можно обновить логику на стороне клиента, чтобы направить запросы в соответствующие индексы на основе фильтров. Однако constant_keyword делает это прозрачным и позволяет отделить запросы поиска от топологии индексов в обмен на очень низкую нагрузку.
© 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/faster-filtering-with-constant-keyword.html