GraphQL: фильтрация данных в массиве
Я уверен, что это простая вещь, но я ничего не мог найти ни в документе GraphQL, ни в Graphcool.
скажем, у меня есть сущность с этой схемой (новый пользователь GraphQL, извините, если я ошибаюсь в представлении схемы):
Book {
name: String!
author: String!
categories: [String!]
}
как бы я сделал запрос для всех книг, которые являются частью "mystery"
категория? Я знаю, что могу фильтровать с allBooks(filter: {})
, а categories_in: ["mystery"]
и categories_contains: "mystery"
трюк не сработал.
2 ответов
Category
модель
подумав немного больше об этой ситуации, создавая Category
модель, безусловно,путь.
например, представьте, что вы хотите, чтобы позволить читателям подписаться на свои любимые категории позже. Или, что, если вам нужен список всех существующих категорий? Используя списки строк, вам нужно будет запросить все книги и каким-то образом обработать все полученные категории. Обработка этого на уровне модели, а не с помощью списков строк чувствует себя намного больше природный.
вместо этого вы можете создать новый Category
модель и добавить отношение "многие ко многим" между Category
и Book
. В таких ситуациях мне нравится добавлять уникальное поле перечисления tag
и в строке text
. (Уникальное строковое поле tag
один также был бы подходящим, вероятно, вопрос вкуса.)
С этой установкой, вы можете легко выполнить требования к данным как
книги, которые назначаются с учетом категория?
query {
# query books by unique category tag
Category(tag: MYSTERY) {
books {
id
}
}
# query books by specific category text
Category(filter: {
text: "mystery"
}) {
books {
id
}
}
}
какие книги относятся по крайней мере к одной категории данного списка?
query {
allCategories(filter: {
OR: [{
tag: MYSTERY
}, {
tag: MAGIC
}]
}) {
books {
id
}
}
}
какие книги назначаются всем категориям данного списка?
query {
allCategories(filter: {
AND: [{
tag: MYSTERY
}, {
tag: MAGIC
}]
}) {
books {
id
}
}
}
соответствующих фильтров
несмотря на то, что вышеуказанные запросы удовлетворяют указанным требованиям к данным, Книги группируются по Category
в ответе, что означает, что нам придется сгладить группы на клиент.
С так называемыми связанными фильтрами мы можем повернуть это, чтобы получить книги только на основе условий, определенных его связанными категориями.
например, на запрос книги, отнесенные по крайней мере к одной категории данного списка:
query {
allBooks(filter: {
OR: [{
categories_some: {
tag: MYSTERY
},
categories_some: {
tag: MAGIC
}
}]
}) {
id
}
}
если вы заинтересованы в использовании размещенного сервиса GraphQL, скафолд.Ио имеет эту функцию в течение некоторого времени. Все поля подключения в вашем API поставляются с WhereArgs
аргумент, который предоставляет фильтры, которые позволяют вам действительно копаться в ваших данных. Когда у вас есть список скаляров, подобных этому, WhereArgs включают contains
& notContains
поле, которое позволяет фильтровать результаты на основе значений в списке. Это позволяет сделать такой запрос.
query MysteriousBooks($where:BookWhereArgs) {
viewer {
allBooks(where:$where) {
edges { node { title, ... } }
}
}
}
# Variables
{
"where": {
"categories": {
"contains": "mystery"
}
}
}
просто чтобы быть полным, вы также можете выполнить небольшую корректировку схемы, чтобы сделать эту работу без фильтрации скалярного списка. Например, вы можете сделать Category
тип реализации узла, а затем создайте соединение между Category
и Book
. Хотя Book
вероятно, не будет иметь много категорий, это позволит вам выдать такой запрос:
query MysteriousBooks($where: CategoryWhereArgs) {
viewer {
allCategories(where: $where) {
books {
edges { node { title, ... } }
}
}
}
}
# Variables
{
"where": {
"name": {
"eq": "mystery"
}
}
}
если вы структурируете свою схему таким образом, вы также сможете сделать больше фильтрации в книгах в категории без необходимости просматривать каждую книгу в вашем архиве. Например, вы могли бы эффективно попросить " все таинственные книги, написанные в прошлом году."
полное раскрытие: я работаю в Scaphold, и хотя я бы хотел, чтобы вы не испытывали никаких обид, если вы не переключитесь. Я рад видеть, что люди пытаются и любят GraphQL. Если вам интересно, о том, как реализовать этот тип поведения на вашем сервере, дайте мне знать, и я буду рад помочь там!
Я надеюсь, что это помогает!