Фильтрация и сортировка
На странице GraphQL API — краткая сводка операторов. Здесь — полный справочник: все операторы по типам полей, комбинаторы, сортировка, системные колонки и наследованные поля.
Фильтр Where
Структурированный фильтр передаётся в аргументе where:
query {
blogPosts(where: { status: { eq: "published" } }) {
id title
}
}
Каждое поле в where — это объект с оператором. Тип оператора зависит от
типа поля.
Операторы по типам полей
| Тип поля | Операторы |
|---|---|
| Строка, Текст, Список | eq, neq, in, notIn, contains, startsWith, endsWith |
| Число | eq, neq, gt, gte, lt, lte, in |
| Логический | eq |
| Дата, Дата и время | eq, neq, gt, gte, lt, lte |
| Тип контента (ссылка) | eq, in |
| Массив (значений) | contains, eq, in, notIn |
Примеры:
# Строка: подстрока (без учёта регистра)
where: { title: { contains: "vue" } }
# Число: больше или равно
where: { view_count: { gte: 100 } }
# Логический: равно
where: { featured: { eq: true } }
# Дата: больше (ISO 8601)
where: { published_at: { gt: "2026-01-01T00:00:00Z" } }
# Ссылка: равно (по ID)
where: { author: { eq: "550e8400-e29b-41d4-a716-446655440000" } }
# Массив: содержит (проверка вхождения элемента)
where: { tags: { contains: "vue" } }
# Множественный выбор
where: { status: { in: ["draft", "review"] } }
Регистр
contains, startsWith, endsWith — без учёта регистра (ILIKE).
eq и neq на строках — с учётом регистра. { title: { eq: "Vue" } }
не найдёт "vue", но { title: { contains: "vue" } } найдёт.
Пустые списки
{ slug: { in: [] } } возвращает 0 записей.
{ slug: { notIn: [] } } возвращает все записи.
Комбинаторы AND / OR / NOT
Поля на одном уровне объединяются через AND (неявно):
where: {
status: { eq: "published" } # AND
view_count: { gte: 100 } # AND
}
OR — список фильтров (выполняется хотя бы один):
where: {
title: { contains: "Vue" }
OR: [
{ status: { eq: "draft" } }
{ view_count: { gte: 75 } }
]
}
# означает: title contains "Vue" AND (status = draft OR view_count >= 75)
AND — список (явное AND внутри группы):
where: {
AND: [
{ status: { eq: "published" } }
{ author: { eq: "abc-123" } }
]
}
NOT — один объект (не список):
where: {
NOT: { status: { eq: "draft" } }
}
# означает: status ≠ draft
Комбинаторы вкладываются друг в друга без ограничений.
Сортировка (orderBy)
Список полей и направлений:
query {
blogPosts(orderBy: [{ field: PUBLISHED_AT, direction: DESC }]) {
title published_at
}
}
Множественная сортировка — по первому ключу, потом по второму:
orderBy: [{ field: STATUS, direction: DESC }, { field: CREATED_AT, direction: ASC }]
Правила:
- Имена полей — в верхнем регистре (
PUBLISHED_AT,TITLE,CREATED_AT). - Направление:
ASC(по умолчанию) илиDESC. - Массивы сортировать нельзя.
Системные поля
Эти поля есть у каждого типа, независимо от схемы:
| Поле | Фильтр | Сортировка |
|---|---|---|
id |
eq, in |
да |
created_at |
дата | да |
updated_at |
дата | да |
where: { created_at: { gt: "2026-01-01T00:00:00Z" } }
orderBy: [{ field: CREATED_AT, direction: DESC }]
Наследованные поля
Если тип наследует поля через Extends, эти поля тоже доступны для
фильтрации и сортировки. Например, blog-post наследует status от
page — фильтр where: { status: { eq: "published" } } работает.
Какие поля НЕ фильтруются
- JSON — произвольный JSON нельзя сравнить.
- Полиморфные блоки (
blocksу Page — Тип контента + массив без указания типа) — нельзя фильтровать и сортировать. - Неизвестное поле в
whereвызывает ошибку.
Search vs Where
Аргумент search — поиск подстроки по всем значениям записи и по её ID
(ILIKE по JSONB и колонке id). Комбинируется с where через AND:
blogPosts(search: "vue", where: { status: { eq: "published" } })
search ищет везде, where фильтрует по конкретным полям.
Count с фильтром
blogPostsCount(where: { status: { eq: "published" } })
Возвращает количество записей под фильтром — для пагинации. Игнорирует
limit и offset.
Что дальше
- Вебхуки — события жизненного цикла записей.
- GraphQL API — общий обзор запросов и мутаций.
- Типы контента и поля — какие бывают поля.