FT.SEARCH
FT.SEARCH — это команда (инструкция) языка запросов модуля расширения RediSearch, предназначенного для полнотекстового поиска в системе управления базами данных Redis. Команда FT.SEARCH выполняет поиск по проиндексированным текстовым полям, возвращая документы, соответствующие заданному запросу, с возможностью ранжирования, фильтрации, агрегации и подсветки результатов.
История и контекст
Redis изначально проектировался как высокопроизводительное хранилище типа «ключ-значение» (key-value store), не поддерживающее сложные операции поиска по содержимому значений. Для решения этой задачи компания Redis Ltd. (ранее Redis Labs) разработала модуль RediSearch, который впервые был выпущен в 2016 году. Модуль реализует полнотекстовый поиск на основе инвертированных индексов, хранящихся непосредственно в Redis, что позволяет выполнять поисковые запросы с минимальной задержкой.
Команда FT.SEARCH является основной поисковой инструкцией модуля. Она пришла на смену более ранним, менее функциональным подходам, таким как ручное сканирование ключей или использование внешних поисковых систем (например, Elasticsearch) в связке с Redis. С момента появления RediSearch стал стандартным инструментом для организации поиска в приложениях, использующих Redis, особенно в сценариях, требующих высокой производительности (например, поиск товаров в интернет-магазинах, поиск по логам, автодополнение).
Синтаксис и параметры
Команда FT.SEARCH имеет следующий обобщённый синтаксис:
`` FT.SEARCH index query [OPTIONS ...] ``
Основные параметры:
- index — имя индекса, созданного ранее командой
FT.CREATE. Индекс определяет, какие поля документов (хэшей или JSON-объектов) проиндексированы и доступны для поиска. - query — строка запроса, написанная на специальном языке запросов RediSearch. Поддерживает логические операторы (
AND,OR,NOT), группировку скобками, поиск по фразе, префиксный и суффиксный поиск, нечёткий поиск (fuzzy search), поиск по синонимам, взвешивание полей и другие возможности.
Ключевые опции команды
RETURN {count} {field ...}— ограничивает набор полей, возвращаемых в результатах. По умолчанию возвращаются все поля.LIMIT {offset} {num}— задаёт смещение и количество возвращаемых результатов (аналог пагинации). По умолчанию возвращается 10 результатов.SORTBY {field} [ASC|DESC]— сортирует результаты по указанному полю (должно быть проиндексировано как числовое или текстовое с возможностью сортировки).FILTER {numeric_field} {min} {max}— фильтрует результаты по числовому полю, задавая диапазон значений.GEOFILTER {geo_field} {lon} {lat} {radius} {unit}— фильтрует результаты по географическому положению (если поле проиндексировано как географическое).HIGHLIGHT [FIELDS {count} {field ...}] [TAGS {open} {close}]— подсвечивает совпадения в тексте, обрамляя их заданными тегами (по умолчанию<b>и</b>).SUMMARIZE [FIELDS {count} {field ...}] [FRAGS {num}] [LEN {fraglen}] [SEPARATOR {separator}]— возвращает фрагменты текста вокруг совпадений, а не весь текст целиком.INKEYS {count} {key ...}— ограничивает поиск только указанными ключами.NOCONTENT— возвращает только идентификаторы документов (ключи), без содержимого.WITHSCORES— включает в результат оценку релевантности (score) для каждого документа.WITHPAYLOADS— включает в результат полезную нагрузку (payload), если она была задана при индексации.LANGUAGE {lang}— задаёт язык для стемминга (например,english,russian,chinese). По умолчанию —english.
Язык запросов
Язык запросов RediSearch, используемый в FT.SEARCH, поддерживает несколько типов поисковых выражений:
- Простой поиск по слову:
word— ищет документы, содержащие точное слово. - Поиск по фразе:
"word1 word2"— ищет точную последовательность слов. - Префиксный поиск:
word*— ищет слова, начинающиеся сword. - Суффиксный поиск:
*word— ищет слова, заканчивающиеся наword(требует включения опцииSUFFIXпри создании индекса). - Нечёткий поиск:
%%word%%— ищет слова, похожие наword(с расстоянием Левенштейна до 2). - Логические операторы:
word1 word2— эквивалентноAND(оба слова должны присутствовать).word1 | word2— операторOR(хотя бы одно слово).-word— операторNOT(исключает документы, содержащие слово).- Группировка:
(word1 | word2) word3— позволяет задавать приоритет операций. - Взвешивание полей:
word => { $weight: 2.0 }— увеличивает вес поля при расчёте релевантности. - Поиск по синонимам: если для индекса определена группа синонимов, запрос
wordбудет автоматически расширяться на все синонимы из группы.
Индексация и производительность
Для работы FT.SEARCH необходимо предварительно создать индекс с помощью команды FT.CREATE. Индекс может быть построен на основе хэшей (тип данных hash) или JSON-объектов (тип данных JSON). При создании индекса указываются поля, которые будут участвовать в поиске, их тип (текстовый, числовой, географический, теговый) и дополнительные параметры (например, вес поля, возможность сортировки, язык стемминга).
Производительность FT.SEARCH обусловлена использованием инвертированных индексов, хранящихся в оперативной памяти Redis. Это обеспечивает время отклика на уровне миллисекунд даже при объёмах индекса в десятки и сотни миллионов документов. Однако, поскольку индекс полностью хранится в RAM, требования к памяти могут быть значительными: размер индекса обычно составляет 50–100% от размера исходных данных.
Пример использования
Предположим, создан индекс idx:products для хэшей, представляющих товары, с текстовыми полями name и description, а также числовым полем price. Команда:
`` FT.SEARCH idx:products "ноутбук" RETURN 3 name price description LIMIT 0 5 SORTBY price ASC ``
Вернёт первые 5 товаров, содержащих слово «ноутбук» в любом из проиндексированных текстовых полей, отсортированных по возрастанию цены, и выведет только поля name, price и description.
Сравнение с альтернативами
FT.SEARCH часто сравнивают с поисковыми возможностями других NoSQL-решений и специализированных поисковых систем:
- Elasticsearch — более тяжёлая и функционально богатая система, работающая как отдельный сервис. RediSearch, в отличие от неё, встроен непосредственно в Redis, что упрощает архитектуру и снижает задержки, но ограничивает объём хранимых данных (из-за RAM-зависимости) и сложность аналитических запросов.
- MongoDB — поддерживает текстовый поиск через индексы
text, но он менее производителен и гибок по сравнению с RediSearch, особенно в части нечёткого поиска и ранжирования. - SQLite FTS — встраиваемая полнотекстовая поисковая система, работающая на диске. RediSearch быстрее, но требует больше оперативной памяти.
Ограничения и недостатки
- Зависимость от оперативной памяти: весь индекс должен помещаться в RAM. При больших объёмах данных (терабайты) это может быть экономически невыгодно.
- Отсутствие распределённости «из коробки»: RediSearch не поддерживает шардирование индекса между несколькими узлами Redis. Для масштабирования требуется использование кластерного режима Redis Cluster, который имеет ограничения на операции с перекрёстными слотами.
- Ограниченная поддержка сложных аналитических запросов:
FT.SEARCHне предназначен для агрегаций, группировок и статистических вычислений, характерных для Elasticsearch или SQL. - Необходимость предварительного создания индекса: индексация происходит асинхронно, и новые данные не будут доступны для поиска до завершения индексации.
Применение
FT.SEARCH широко используется в веб-приложениях, мобильных сервисах, системах электронной коммерции, поиске по логам, чат-ботах и других сценариях, где требуется быстрый полнотекстовый поиск с минимальной задержкой и без развёртывания отдельного поискового сервера. Типичные примеры: поиск товаров в интернет-магазине, поиск пользователей по имени, поиск по содержимому документов или сообщений.
Источники
- Документация Redis — RediSearch: команда FT.SEARCH (redis.io/docs/latest/commands/ft.search/)
- Руководство по языку запросов RediSearch (redis.io/docs/latest/develop/interact/search-and-query/query/)
- Статья «RediSearch: A Full-Text Search Engine for Redis» (Redis Labs Engineering Blog, 2016)
- Книга «Redis in Action» by Josiah L. Carlson (Manning Publications, 2013) — глава о модулях Redis
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →