Запросы к Elasticsearch пишутся на Query DSL, языке запросов в формате JSON. Самые частые запросы в нём match и term, и самая частая ошибка новичка их перепутать. Выглядят они похоже, а работают по-разному. Разберёмся почему.
Вспомним анализ
В уроке про маппинг мы видели два вида строковых полей. Поле text при записи разбирается анализатором: «Пицца Маргарита» превращается в термины пицц и маргарит, нижний регистр и без окончаний. Поле keyword хранит строку целиком, как есть: «Пицца Маргарита» с большими буквами.
В индексе лежат именно термины. Поиск это сравнение термина из запроса с терминами в индексе.
match: поиск для людей
match сначала прогоняет текст запроса через тот же анализатор, что и поле. «Пиццы Маргарита» превращается в пицц и маргарит, и только потом ищется. Поэтому регистр и окончания не важны.
По умолчанию match ищет документы, где есть хотя бы одно слово запроса, а выше ставит те, где совпало больше. Чтобы требовать все слова, есть "operator": "and":
{ "match": { "name": { "query": "пицца маргарита", "operator": "and" } } }
term: точное значение
term ничего с запросом не делает. Он берёт значение как есть и ищет ровно такой термин. Это то, что нужно для полей keyword, чисел и дат: кухня «итальянская», тег spicy, статус, _id.
А вот term по полю text почти всегда ошибка. В индексе поля name нет термина «Пицца Маргарита»: там лежат пицц и маргарит. Запрос term с «Пицца Маргарита» не найдёт ничего, хотя таких блюд в каталоге несколько. Найдёт только term по основе пицц, но угадывать основы руками никто не будет.
урок из курса
Урок из курса «Elasticsearch и ELK». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.