For arbitrary expression with binding to entity fields, use the method
whereExpr
Available from the main module version 20.400.0.
:
\Bitrix\Main\UserTable::query()
->whereExpr('JSON_CONTAINS(%s, 4)', ['SOME_JSON_FIELD'])
->exec();
// WHERE JSON_CONTAINS(`main_user`.`SOME_JSON_FIELD`, 4)
Expression arguments and multipart fields are similar to the ExpressionField constructor and are inserted using the function
sprintfsprintf — Returns formatted string. Learn more in the PHP documentation.
.
List of operators is stored at \Bitrix\Main\ORM\Query\Filter\Operator::$operators (see array keys):
= , <> , != , < , <= , > , >= , in , between , like , exists
Comparison with another field
Separate method whereColumn simplifies the field comparison to one another:
\Bitrix\Main\UserTable::query()
->whereColumn('NAME', 'LOGIN')
->exec();
// WHERE `main_user`.`NAME` = `main_user`.`LOGIN`
This method is not significantly different from the where method, and formally it's the same call with a small wrapper:
\Bitrix\Main\UserTable::query()
->where('NAME', new Query\Filter\Expression\Column('LOGIN'))
->exec();
// WHERE `main_user`.`NAME` = `main_user`.`LOGIN`
whereColumn provides a flexible use for columns used in filter, for example:
\Bitrix\Main\UserTable::query()
->whereIn('LOGIN', [
new Column('NAME'),
new Column('LAST_NAME')
])
->exec();
// WHERE `main_user`.`LOGIN` IN (`main_user`.`NAME`, `main_user`.`LAST_NAME`)
Columns can be used in any operator. They can be perceived specifically as fields for specific entities and not just arbitrary SQL expression.
Multiple conditions
The following record is presented for several conditions:
\Bitrix\Main\UserTable::query()
->where('ID', '>', 1)
->where('ACTIVE', true)
->whereNotNull('PERSONAL_BIRTHDAY')
->whereLike('NAME', 'A%')
->exec();
// WHERE `main_user`.`ID` > 1 AND `main_user`.`ACTIVE` = 'Y' AND `main_user`.`PERSONAL_BIRTHDAY` IS NOT NULL AND `main_user`.`NAME` LIKE 'A%'
Note: boolean fields with values Y/N, 1/0 and etc. can use true and false.
When you need to indicate several conditions in a single call, use the following format: (operator methods can be replaced by operator codes)
\Bitrix\Main\UserTable::query()
->where([
['ID', '>', 1],
['ACTIVE', true],
['PERSONAL_BIRTHDAY', '<>', null],
['NAME', 'like', 'A%']
])
->exec();
// WHERE `main_user`.`ID` > 1 AND `main_user`.`ACTIVE` = 'Y' AND `main_user`.`PERSONAL_BIRTHDAY` IS NOT NULL AND `main_user`.`NAME` LIKE 'A%'
OR and nested filters
Storage of all filter conditions in Query uses the condition container \Bitrix\Main\Entity\Query\Filter\ConditionTree. In addition to standard conditions, allows to add several instances of ConditionTree, thus creating any levels of branching and nesting depth.
All calls of where shown above - is proxying to base container. Next two calls will lead to completely identical result:
Descriptions of references is provided in the following format:
new Entity\ReferenceField('GROUP', GroupTable::class,
Join::on('this.GROUP_ID', 'ref.ID')
)
The method `on` is a brief and more semantically proper record Query::filter() with preset condition per columns. Returns filter instance and can build any conditions for JOIN:
new Entity\ReferenceField('GROUP', GroupTable::class,
Join::on('this.GROUP_ID', 'ref.ID')
->where('ref.TYPE', 'admin')
->whereIn('ref.OPTION', [
new Column('this.OPTION1'),
new Column('this.OPTION2'),
new Column('this.OPTION3')
]
)
Anywhere with indicated field names its implied that you can specify any chain of branching:
There is an existing method for conversion from array to object \Bitrix\Main\ORM\Query\Filter\ConditionTree::createFromArray to use filter as an array. Array format looks as follows:
the rest of methods where* are replaced by corresponding comparison operators in, between, like and etc.
['FIELD', 'in', [5, 7, 11]]
Attention: exercise close caution when using arrays. Do not insert unchecked data, passed by user, as a filter due to the possible dangerous conditions for data deployment in the database. Please, verify all input conditions using the field whitelist.