Пакет · mui-data-grid

Операторы

Оператор — вторая часть элемента фильтра: { field, operator, value }. Здесь собраны все поддерживаемые операторы, SQL, в который каждый превращается, и таблица того, какие из них принимает колонка в зависимости от объявленного типа.

Перечисление MGOperator

Строки — те же, что присылает MUI X DataGrid; отправляйте их из интерфейса как есть. Приведение к перечислению происходит при гидрации запроса: неизвестная строка отклоняется ещё до того, как запрос доберётся до схемы.

Категория Оператор Case перечисления
Строковые contains MGOperator::CONTAINS
notContains MGOperator::NOT_CONTAINS
startsWith MGOperator::STARTS_WITH
endsWith MGOperator::ENDS_WITH
Равенство equals MGOperator::EQUALS
is MGOperator::IS
not MGOperator::NOT
= MGOperator::EQ
!= MGOperator::NEQ
Сравнение > MGOperator::GT
>= MGOperator::GTE
< MGOperator::LT
<= MGOperator::LTE
Даты after MGOperator::AFTER
onOrAfter MGOperator::ON_OR_AFTER
before MGOperator::BEFORE
onOrBefore MGOperator::ON_OR_BEFORE
Множество isAnyOf MGOperator::IS_ANY_OF
Пустота isEmpty MGOperator::IS_EMPTY
isNotEmpty MGOperator::IS_NOT_EMPTY

Операторы для дат — синонимы операторов сравнения: они существуют потому, что интерфейс таблицы называет их иначе для колонок-дат, а SQL получается тот же.

Оператор → SQL

Оператор SQL
contains col LIKE :v со значением %v% *
notContains col NOT LIKE :v со значением %v% *
startsWith col LIKE :v со значением v% *
endsWith col LIKE :v со значением %v *
equals · is · = col = :v
not · != col != :v
> · after col > :v
>= · onOrAfter col >= :v
< · before col < :v
<= · onOrBefore col <= :v
isAnyOf col IN (:v0, :v1, …) — пустой набор даёт пустое условие
isEmpty col IS NULL
isNotEmpty col IS NOT NULL

* Четыре первых оператора регистронезависимы, а в SQL это пишется по-разному в разных СУБД: ILIKE в PostgreSQL, LIKE в MySQL и SQLite, lower(col) LIKE lower(:v) как портируемый вариант. Написание выбирается автоматически — см. Режимы совпадения.

Значение всегда уходит связанным параметром: подстановка % в шаблон делается на стороне PHP, а не склейкой строк в SQL.

Перечисление FilterType

Тип объявляется у колонки через filterable() и работает шлюзом: оператор вне набора отклоняется с кодом 400 до того, как дойдёт до SQL. Это защищает запрос не только от злонамеренного, но и от просто неверно настроенного интерфейса.

FilterType Разрешённые операторы
String contains, notContains, startsWith, endsWith, equals, is, not, =, !=, isAnyOf, isEmpty, isNotEmpty
Number equals, is, not, =, !=, >, >=, <, <=, isAnyOf, isEmpty, isNotEmpty
Boolean is, equals, =, isEmpty, isNotEmpty
Date is, not, equals, =, !=, after, onOrAfter, before, onOrBefore, isEmpty, isNotEmpty

Та же матрица, если смотреть со стороны оператора:

Оператор String Number Boolean Date
contains · notContains · startsWith · endsWith
equals · is · =
not · !=
> · >= · < · <=
after · onOrAfter · before · onOrBefore
isAnyOf
isEmpty · isNotEmpty

Выбирайте тип по поведению значения в SQL

Тип здесь — не про тип в PHP, а про то, какие сравнения имеют смысл. Колонку со статусом, которую сравнивают только на равенство и вхождение в набор, разумно объявить String, даже если в базе это smallint. А метку времени — Date, чтобы получить операторы диапазона и не получить contains.

Пример отказа

php
GridColumn::for('views', 'a.views')->filterable(FilterType::Number);
json
{ "field": "views", "operator": "contains", "value": "1" }
json
{ "message": "Operator 'contains' is not allowed for field 'views'" }

Объединение условий: AND и OR

Поле logicOperator модели фильтров решает, как складываются элементы. Значение проверяется на этапе гидрации: принимаются только and и or в любом регистре, по умолчанию — and.

json
{
"filterModel": {
  "logicOperator": "or",
  "items": [
    { "field": "title",      "operator": "contains", "value": "sql" },
    { "field": "authorName", "operator": "contains", "value": "sql" }
  ]
}
}

Результат

sql
((a.title LIKE :iqb0 OR au.name LIKE :iqb1))

Внешние скобки добавляются намеренно: без них OR смешался бы с вашим базовым WHERE через AND и изменил смысл запроса.

Крайние случаи

Случай Поведение
items пуст условие не добавляется, базовый WHERE не тронут
isAnyOf с пустым массивом элемент пропускается, остальные применяются
все элементы дали пустое условие условие не добавляется
value отсутствует у isEmpty / isNotEmpty нормально, значение этим операторам не нужно
неизвестная строка оператора 400 на этапе гидрации запроса
поле не объявлено в схеме 400 из схемы

Что дальше