Настоящий поиск в каталоге «Гонца» это не одно условие. Клиент набрал «пицца», а ещё в приложении включены фильтры: только то, что сейчас в наличии, дешевле 500 рублей, без острого. И хорошо бы выше показать пиццы с грибами, потому что клиент их часто заказывает. Собрать такие условия в один запрос помогает bool.
Четыре корзины условий
bool раскладывает условия по четырём корзинам:
| Корзина | Документ обязан подходить? | Влияет на _score? |
|---|---|---|
must | да | да |
filter | да | нет |
must_not | обязан не подходить | нет |
should | нет, если есть must или filter | да, совпадение поднимает выше |
{
"query": {
"bool": {
"must": [ { "match": { "name": "пицца" } } ],
"filter": [ { "term": { "available": true } },
{ "range": { "price_rub": { "lte": 500 } } } ],
"must_not": [ { "term": { "tags": "spicy" } } ],
"should": [ { "match": { "description": "грибы" } } ]
}
}
}
В каждой корзине массив запросов, и их можно вкладывать: внутри should может стоять ещё один bool.
Запрос и фильтр
Самое важное различие здесь между must и filter. У Elasticsearch два режима условий:
- контекст запроса: насколько хорошо документ подходит? Здесь считается
_score. Этоmustиshould; - контекст фильтра: подходит или нет? Только да или нет, без оценки. Это
filterиmust_not.
Цена дешевле 500 рублей либо выполняется, либо нет: «насколько хорошо» тут не бывает. Если положить такое условие в must, оно всё равно будет участвовать в подсчёте оценки и чуть-чуть сдвигать порядок без всякого смысла. А в filter оно просто отсекает лишнее. Есть и второй выигрыш: Elasticsearch кэширует результаты частых фильтров, и повторный запрос с теми же фильтрами идёт быстрее.
Правило простое: всё, что про точное совпадение (кухня, наличие, цена, дата, тег), идёт в filter. Всё, что про слова и «насколько подходит», в must и should.
урок из курса
Урок из курса «Elasticsearch и ELK». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.