Фильтры
filter()
Фильтры используются для точечной выборки данных из БД
Например, мы можем получить список пользователей с положительным балансом так:
{{ FOR u IN user.filter( balance = isPositive ).items }}
...
{{ END }}
Синтаксис фильтрации
Важные правила синтаксиса
Кавычки для ключей:
- Кавычки НЕ обязательны для обычных ключей:
status = 1
,balance = gt(0)
- Кавычки ОБЯЗАТЕЛЬНЫ только для ключей, содержащие спец. символы:
'-or'
,'-and'
,=
,!=
,a.b
…
Запятые:
- В однострочном синтаксисе запятые обязательны:
filter( status = 1, balance = gt(0) )
- В многострочном синтаксисе запятые НЕ нужны при разделении переносом строки
Основные правила записи
Простые значения можно записывать напрямую без использования специальных функций:
{{ FOR u IN user.filter( status = 1 ).items }}
Пользователь {{ u.login }} со статусом 1
{{ END }}
Это эквивалентно использованию eq()
:
{{ FOR u IN user.filter( status = eq(1) ).items }}
То же самое, что и выше
{{ END }}
Строковые значения также можно записывать напрямую:
{{ FOR u IN user.filter( role = "admin" ).items }}
Администраторы
{{ END }}
Когда использовать функции сравнения
Функции сравнения (eq()
, ne()
, gt()
, etc.) нужны в следующих случаях:
1. Для явного указания типа сравнения:
{{ FOR u IN user.filter( balance = isPositive ).items }}
Пользователи с положительнрым балансом
{{ END }}
2. Для операторов отличных от равенства:
{{ FOR u IN user.filter( age = gt(18) ).items }}
Пользователи старше 18 лет
{{ END }}
3. Для текстовых полей, когда нужно точное совпадение:
{{ FOR u IN user.filter( login = eq("admin") ).items }}
Точно "admin", а не LIKE 'admin' (LIKE регистронезависимый)
{{ END }}
4. В JSON полях для лучшей читаемости:
{{ FOR u IN user.filter( settings = { status = ne(0) } ).items }}
Пользователи с активными настройками
{{ END }}
Краткие формы записи
Полная форма | Краткая форма | Описание |
---|---|---|
status = eq(1) |
status = 1 |
Равенство |
enabled = eq(true) |
enabled = true |
Boolean значения |
role = eq("admin") |
role = "admin" |
Строки (для точного сравнения) |
name = eq("") |
name = "" |
Пустая строка |
Специальные случаи
Текстовые поля с LIKE:
# Автоматический LIKE поиск
{{ FOR u IN user.filter( name = "%Петр%" ).items }}
# Точное сравнение
{{ FOR u IN user.filter( name = eq("Петр") ).items }}
Boolean значения:
# Все эти записи эквивалентны
{{ FOR u IN user.filter( enabled = true ).items }}
{{ FOR u IN user.filter( enabled = eq(true) ).items }}
{{ FOR u IN user.filter( enabled = 1 ).items }}
{{ FOR u IN user.filter( enabled = eq(1) ).items }}
NULL значения:
# Простая запись
{{ FOR u IN user.filter( manager_id = null ).items }}
{{ FOR u IN user.filter( manager_id = { '!=' = null } ).items }}
# С функцией
{{ FOR u IN user.filter( manager_id = isNull ).items }}
{{ FOR u IN user.filter( manager_id = isNotNull ).items }}
Многострочный синтаксис
В многострочных фильтрах действуют особые правила:
1. Запятые не требуются при разделении ключ-значение переносом строки:
{{ FOR u IN user.filter(
balance = gt(0)
status = ne(0)
description = isNotEmpty
).items }}
Фильтр без запятых
{{ END }}
2. Сравнение однострочного и многострочного синтаксиса:
# Однострочный (с запятыми)
{{ FOR u IN user.filter( status = 1, balance = gt(0), role = "admin" ).items }}
# Многострочный (без запятых)
{{ FOR u IN user.filter(
status = 1
balance = gt(0)
role = "admin"
).items }}
Принципы работы фильтрации
Логический оператор “И” (AND)
По умолчанию все условия, перечисленные через запятую, объединяются логическим оператором “И”:
{{ FOR u IN user.filter(
balance = gt(0)
status = 1
created = ge('2024-01-01')
).items }}
Пользователь {{ u.login }} соответствует ВСЕМ условиям одновременно
{{ END }}
Это эквивалентно SQL: WHERE balance > 0 AND status = 1 AND created >= '2024-01-01'
Логический оператор “ИЛИ” (OR)
Для реализации логики “ИЛИ” есть несколько способов:
Способ 1: Использование специального ключа -or
{{ FOR u IN user.filter( '-or' = { balance = 0, login = "test" } ).items }}
Пользователь {{ u.login }} с нулевым балансом ИЛИ логином "test"
{{ END }}
Можно комбинировать -or
с обычными условиями:
{{ FOR u IN user.filter(
status = 1
'-or' = {
balance = gt(1000)
settings = { vip = true }
}
).items }}
Активный пользователь с балансом больше 1000 ИЛИ VIP статусом
{{ END }}
Способ 2: Объединение результатов нескольких фильтров
{{ SET positive_users = user.filter( balance = gt(0) ).items }}
{{ SET premium_users = user.filter( status = eq(2) ).items }}
{{ FOR u IN positive_users.merge(premium_users).unique }}
Пользователь {{ u.login }} имеет положительный баланс ИЛИ премиум статус
{{ END }}
Способ 3: Массивы значений для одного поля
{{ FOR u IN us.filter( status = [STATUS_ACTIVE,STATUS_BLOCK,STATUS_WAIT_FOR_PAY] ).items }}
Услуги пользователя с указанными статусами
{{ END }}
Автоматическое использование LIKE для текстовых полей
Для текстовых полей в базе данных автоматически применяется оператор LIKE
при использовании символов подстановки %
. Это позволяет выполнять гибкий поиск по шаблонам.
Принцип работы
Когда вы указываете значение для текстового поля, система автоматически:
- Определяет тип поля в структуре таблицы
- Если поле имеет текстовый тип (
text
,varchar
, etc.) И значение содержит символы%
, применяет операторLIKE
- Если символов
%
нет, используется точное сравнение=
Примеры LIKE поиска
Поиск по подстроке в имени:
{{ FOR u IN user.filter(full_name = "%Иван%").items }}
Найден пользователь {{ u.login }} с именем содержащим "Иван"
{{ END }}
Генерирует SQL: WHERE full_name LIKE '%Иван%'
Поиск по началу логина:
{{ FOR u IN user.filter(login = "admin%").items }}
Найден пользователь {{ u.login }} начинающийся с "admin"
{{ END }}
Генерирует SQL: WHERE login LIKE 'admin%'
Поиск по окончанию email:
{{ FOR u IN user.filter(email = "%@company.com").items }}
Пользователи с корпоративным email
{{ END }}
Генерирует SQL: WHERE email LIKE '%@company.com'
Точное совпадение для текстовых полей
Если вам нужно точное совпадение, НЕ используйте символы %
:
{{ FOR u IN user.filter(login = "admin").items }}
Пользователь с точным логином "admin"
{{ END }}
Генерирует SQL: WHERE login LIKE 'admin'
Альтернативно, можно использовать оператор eq()
:
{{ FOR u IN user.filter(login = eq("admin")).items }}
Пользователь с точным логином "admin"
{{ END }}
Генерирует SQL: WHERE login = 'admin'
Кастомные LIKE паттерны
Для более сложных паттернов поиска используйте явное указание LIKE операторов:
{{ FOR u IN user.filter(email = { '-like' = "%@gmail.com" }).items }}
Пользователи с email на Gmail
{{ END }}
{{ FOR u IN user.filter(login = { '-not_like' = "test%" }).items }}
Пользователи, логин которых НЕ начинается с "test"
{{ END }}
Смешанные условия с LIKE
{{ FOR u IN user.filter(
full_name = "%Петр%"
email = "%@company.com"
status = eq(1)
).items }}
Активные пользователи с именем содержащим "Петр" и корпоративным email
{{ END }}
В этом примере:
full_name LIKE '%Петр%'
(LIKE из-за символов %)email LIKE '%@company.com'
(LIKE из-за символов %)status = 1
(точное сравнение для числового поля)
Важно: Символы %
нужно добавлять самостоятельно для активации LIKE поиска!
Работа с JSON полями
Важно: Для работы с JSON полями используйте формат json_поле = { 'ключ' = значение }
, а НЕ 'json_поле.ключ' = значение
.
Для фильтрации по полям внутри JSON используйте хеш с ключами JSON полей:
{{ FOR u IN user.filter(settings = { notifications = true }).items }}
Пользователь {{ u.login }} с включенными уведомлениями
{{ END }}
Для вложенных JSON структур:
{{ FOR u IN user.filter( profile = { 'preferences.theme' = 'dark' }).items }}
Пользователь {{ u.login }} с темной темой
{{ END }}
Проверка существования JSON поля
Для проверки существования поля в JSON используйте имя поля в точечной нотации:
{{ FOR u IN user.filter(settings = 'notifications').items }}
Пользователь {{ u.login }} у которого есть поле notifications в settings
{{ END }}
Для вложенных полей:
{{ FOR u IN user.filter(settings = 'profile.avatar').items }}
Пользователь {{ u.login }} у которого есть поле profile.avatar в settings
{{ END }}
Проверка отсутствия JSON поля
Для проверки отсутствия поля в JSON используйте префикс !
:
{{ FOR u IN user.filter(settings = '!notifications').items }}
Пользователь {{ u.login }} у которого НЕТ поля notifications в settings
{{ END }}
Для вложенных полей:
{{ FOR u IN user.filter(settings = '!profile.avatar').items }}
Пользователь {{ u.login }} у которого НЕТ поля profile.avatar в settings
{{ END }}
Проверка значений в JSON полях
Для проверки конкретных значений используйте хеш с точечной нотацией:
{{ FOR u IN user.filter(settings = { notifications = true, theme = 'dark' }).items }}
Пользователь {{ u.login }} с темной темой и включенными уведомлениями
{{ END }}
С операторами сравнения:
{{ FOR u IN user.filter(settings = { max_items = gt(10), priority = le(5) }).items }}
Пользователь {{ u.login }} с max_items > 10 и priority <= 5 в настройках
{{ END }}
Комбинирование JSON условий
{{ FOR u IN user.filter(
settings = 'api_key'
settings = { notifications = true, auto_backup = ne(false) }
).items }}
Пользователь {{ u.login }} с API ключом, уведомлениями и автобэкапом
{{ END }}
Проверка JSON полей с специальными функциями
{{ FOR u IN user.filter(settings = { api_key = isNotNull }).items }}
Пользователь {{ u.login }} с настроенным API ключом
{{ END }}
{{ FOR u IN user.filter(profile = { avatar = isEmpty }).items }}
Пользователь {{ u.login }} без аватара в профиле
{{ END }}
Практические примеры синтаксиса
Сравнение различных подходов
Числовые значения:
# Простая запись (рекомендуется для равенства)
{{ FOR u IN user.filter( user_id = 123 ).items }}
# Явная запись (когда нужна ясность)
{{ FOR u IN user.filter( user_id = eq(123) ).items }}
# Операторы сравнения (обязательно через функции)
{{ FOR u IN user.filter( user_id = gt(1000) ).items }}
Строковые значения:
# Точное совпадение
{{ FOR u IN us.filter( status = STATUS_ACTIVE ).items }}
# LIKE поиск (с символами %)
{{ FOR u IN us.filter( status = "%ACTIVE%" ).items }}
# Явное точное совпадение (рекомендуется)
{{ FOR u IN us.filter( status = eq(STATUS_ACTIVE) ).items }}
Boolean значения:
# Простая запись (рекомендуется)
{{ FOR u IN user.filter( enabled = true ).items }}
{{ FOR u IN user.filter( deleted = false ).items }}
# Числовая запись (также работает)
{{ FOR u IN user.filter( enabled = 1 ).items }}
{{ FOR u IN user.filter( deleted = 0 ).items }}
JSON поля:
# Простые значения в JSON
{{ FOR u IN user.filter( settings = { theme = 'dark' } ).items }}
# Функции сравнения в JSON
{{ FOR u IN user.filter( settings = { max_items = gt(10) } ).items }}
# Специальные функции в JSON
{{ FOR u IN user.filter( settings = { api_key = isNotNull } ).items }}
Рекомендации по выбору синтаксиса
Используйте простую запись когда:
- Проверяете равенство:
block = 1
- Работаете с boolean:
enabled = true
- Нужно совпадение строки без учета регистра:
role = "admin"
- Нужно совпадение части строки:
role = "adm%"
Используйте функции когда:
- Нужны операторы сравнения:
age = gt(18)
- Работаете с NULL:
field = isNull
- Нужны специальные проверки:
name = isEmpty
- Нужно точное совпадение строки:
role = eq("admin")
Специальные функции для фильтрации
Проверка на NULL и пустые значения
isNull
Проверяет, что поле равно NULL:
{{ FOR u IN user.filter( avatar = isNull ).items }}
Пользователь {{ u.login }} без аватара
{{ END }}
isNotNull
Проверяет, что поле не равно NULL:
{{ FOR u IN user.filter( avatar = isNotNull ).items }}
Пользователь {{ u.login }} с аватаром
{{ END }}
isEmpty
Проверяет, что поле пустое (NULL или пустая строка):
{{ FOR u IN user.filter( description = isEmpty ).items }}
Пользователь {{ u.login }} без описания
{{ END }}
isNotEmpty
Проверяет, что поле не пустое:
{{ FOR u IN user.filter( description = isNotEmpty ).items }}
Пользователь {{ u.login }} с описанием
{{ END }}
Числовые сравнения
lt(значение)
(<)
Меньше указанного значения:
{{ FOR u IN user.filter( balance = lt(100) ).items }}
Пользователь {{ u.login }} с балансом меньше 100
{{ END }}
gt(значение)
(>)
Больше указанного значения:
{{ FOR u IN user.filter( balance = gt(1000) ).items }}
Пользователь {{ u.login }} с балансом больше 1000
{{ END }}
le(значение)
(<=)
Меньше или равно указанному значению:
{{ FOR u IN user.filter( balance = le(0) ).items }}
Пользователь {{ u.login }} с нулевым или отрицательным балансом
{{ END }}
ge(значение)
(>=)
Больше или равно указанному значению:
{{ FOR u IN user.filter( balance = ge(500) ).items }}
Пользователь {{ u.login }} с балансом от 500
{{ END }}
eq(значение)
(==)
Равно указанному значению:
{{ FOR u IN user.filter( status = eq(1) ).items }}
Активный пользователь {{ u.login }}
{{ END }}
ne(значение)
(!=)
Не равно указанному значению:
{{ FOR u IN user.filter( status = ne(0) ).items }}
Пользователь {{ u.login }} (не заблокирован)
{{ END }}
between(мин, макс)
([..])
Значение в диапазоне (включительно):
{{ FOR u IN user.filter( balance = between(100, 1000) ).items }}
Пользователь {{ u.login }} с балансом от 100 до 1000
{{ END }}
Проверка знака числа
isPositive
(>0)
Проверяет, что значение больше нуля (положительное):
{{ FOR u IN user.filter( balance = isPositive ).items }}
Пользователь {{ u.login }} с положительным балансом
{{ END }}
isNegative
(<0)
Проверяет, что значение меньше нуля (отрицательное):
{{ FOR u IN user.filter( balance = isNegative ).items }}
Пользователь {{ u.login }} с отрицательным балансом
{{ END }}
isNonNegative
(>=0)
Проверяет, что значение больше или равно нулю (неотрицательное):
{{ FOR u IN user.filter( balance = isNonNegative ).items }}
Пользователь {{ u.login }} с неотрицательным балансом
{{ END }}
isNonPositive
(<=0)
Проверяет, что значение меньше или равно нулю (неположительное):
{{ FOR u IN user.filter( balance = isNonPositive ).items }}
Пользователь {{ u.login }} с неположительным балансом
{{ END }}
Сложные примеры фильтрации
Комбинирование разных типов условий
{{ FOR u IN user.filter(
balance = gt(0)
status = ne(0)
description = isNotEmpty
settings = { notifications = true }
created = between('2024-01-01', '2024-12-31')
).items }}
Активный пользователь {{ u.login }} с положительным балансом, описанием,
включенными уведомлениями, созданный в 2024 году
{{ END }}
Фильтрация с использованием JSON и специальных функций
{{ FOR s IN service.filter(
enabled = true
price = ge(100)
config = { auto_renewal = false }
description = isNotEmpty
).items }}
Активная услуга {{ s.name }} стоимостью от 100 без автопродления
{{ END }}
Комбинирование AND и OR условий
{{ FOR u IN user.filter(
status = eq(1)
balance = ge(0)
'-or' = {
profile = { type = 'premium' }
created = ge('2024-01-01')
settings = { notifications = true }
}
).items }}
Активный пользователь с неотрицательным балансом И (премиум профиль ИЛИ создан в 2024 ИЛИ включены уведомления)
{{ END }}
Сложная JSON фильтрация
{{ FOR u IN user.filter(
settings = 'api_key'
settings = '!deprecated_features'
settings = {
max_sessions = gt(1)
auto_logout = true
'security.two_factor' = ne(false)
}
profile = { 'preferences.language' = ['ru', 'en'] }
).items }}
Пользователь {{ u.login }} с API ключом, без устаревших функций,
с настройками безопасности и поддержкой русского или английского языка
{{ END }}
Специальные значения
Также доступны специальные константы:
null
- значение NULLtrue
- логическое истина (1)false
- логическое ложь (0)
{{ FOR s IN service.filter( enabled = true ).items }}
Активная услуга {{ s.name }}
{{ END }}