Блог Горошко Андрея 1C-Битрикс Сложные фильтры в D7 ORM: Query::filter() для логики И/ИЛИ и вложенных условий

Сложные фильтры в D7 ORM: Query::filter() для логики И/ИЛИ и вложенных условий

Средний рейтинг
Еще нет оценок

Простой массив в параметре filter метода getList() отлично подходит для условий, объединенных по логике «И» (AND). Но что делать, если нужна более сложная логика, например, (A AND B) OR C?

Для этого в D7 ORM существует мощный инструмент — объект \Bitrix\Main\ORM\Query\Filter\ConditionTree (дерево условий), который удобно создавать с помощью хелпера Query::filter().

Проблема простого массива

Рассмотрим задачу: найти все активные товары (ACTIVE = ‘Y’), у которых либо цена (PRICE) меньше 1000, либо количество (QUANTITY) равно 0.

Попытка собрать это в простом массиве будет выглядеть громоздко и неинтуитивно:

// Сложно и нечитаемо
'filter' => [
    '=ACTIVE' => 'Y',
    [
        'LOGIC' => 'OR',
        ['<PRICE' => 1000],
        ['=QUANTITY' => 0]
    ]
]

Решение: Query::filter()

Класс Query предоставляет статический метод filter(), который возвращает пустой объект дерева условий. Этот объект имеет методы для построения сложной логики.

Основные методы ConditionTree:

  • where($column, $operator, $value): Добавляет условие (аналог AND).
  • whereIn($column, $values): Условие IN (…).
  • whereNotIn(…), whereLike(…), whereBetween(…) и т.д.
  • logic(‘or’ | ‘and’): Устанавливает, как будут объединяться следующие условия в текущей группе (OR или AND).
  • addCondition(ConditionTree $condition): Добавляет вложенную группу условий.

Пример 1: Простая логика «ИЛИ» (OR)

Найдем элементы, у которых ID равен 10 ИЛИ символьный код равен ‘test’.

use Bitrix\Iblock\ElementTable;
use Bitrix\Main\ORM\Query\Query;

$result = ElementTable::getList([
    'select' => ['ID', 'NAME', 'CODE'],
    'filter' => Query::filter()
        ->logic('or') // Все следующие условия будут объединены через OR
        ->where('ID', 10)
        ->where('CODE', 'test')
]);

// SQL: ... WHERE `ID` = 10 OR `CODE` = 'test'

Пример 2: Комбинация «И» и «ИЛИ»

Вернемся к нашей задаче: активные товары, у которых (цена < 1000 ИЛИ количество = 0).

$result = \Bitrix\Catalog\ProductTable::getList([
    'select' => ['ID', 'QUANTITY'],
    'filter' => Query::filter()
        ->where('ACTIVE', 'Y') // Первое условие (AND)
        ->addCondition( // Добавляем вложенную группу условий
            Query::filter()
                ->logic('or') // Внутри этой группы будет OR
                ->where('PRICE', '<', 1000)
                ->where('QUANTITY', '=', 0)
        )
]);

// SQL: ... WHERE `ACTIVE` = 'Y' AND (`PRICE` < 1000 OR `QUANTITY` = 0)

Как это работает:

  1. Query::filter(): Создает основную группу условий (по умолчанию AND).
  2. ->where(‘ACTIVE’, ‘Y’): Добавляет первое условие в основную группу.
  3. ->addCondition(…): Добавляет новую, вложенную группу.
  4. Внутри addCondition мы создаем еще один объект Query::filter().
  5. ->logic(‘or’): Устанавливаем для вложенной группы логику «ИЛИ».
  6. ->where(…): Добавляем условия уже во вложенную группу.

Передача в getList

Готовый объект фильтра можно передавать в getList напрямую, вместо массива.

$myFilter = Query::filter()
    ->where('IBLOCK_ID', 5)
    ->where('ACTIVE', 'Y');

// ... какая-то логика ...

if ($someCondition) {
    $myFilter->where('PROPERTY_X', 123);
}

$result = ElementTable::getList([
    'select' => ['ID', 'NAME'],
    'filter' => $myFilter // Передаем объект
]);

Вывод:
Использование Query::filter() — это ключ к написанию чистого, читаемого и гибкого кода для выборок данных.

Этот подход позволяет строить фильтры любой сложности, динамически добавляя условия, и делает ваш D7 ORM-код по-настоящему мощным.

D7 ORM, Query::filter, сложные фильтры, ORM ИЛИ, ORM AND, вложенные условия, ConditionTree, Bitrix ORM.

Мой рейтинг:

Добавить комментарий

Related Post

Настройки модулей: COption и современный \Bitrix\Main\Config\OptionНастройки модулей: COption и современный \Bitrix\Main\Config\Option

Средний рейтинг Еще нет оценок Настройки модулей (те, что задаются в административной панели) хранятся в базе данных в таблице b_option. Для программного доступа к этим настройкам в Битрикс есть два API:

Управление заголовками и мета-тегами в Битрикс: SetPageProperty, ShowTitle, ShowMetaУправление заголовками и мета-тегами в Битрикс: SetPageProperty, ShowTitle, ShowMeta

Средний рейтинг Еще нет оценок Правильное управление заголовками (<title>) и мета-тегами (description, keywords, robots) — это фундамент SEO-продвижения. В Битрикс за это отвечает глобальный объект $APPLICATION. С его помощью можно динамически устанавливать и

Чем отличается ядро D7 bitrix и bitrix старое ядроЧем отличается ядро D7 bitrix и bitrix старое ядро

Средний рейтинг Еще нет оценок D7 Bitrix — это новое ядро Битрикс, которое было создано для замены старого ядра. D7 Bitrix является новым ядром разработки, которое было введено в версии