I'm sure it's a simple thing to do, but I couldn't find anything in either GraphQL's doc or Graphcool's.
Say I have an entity with this schema (new GraphQL user, sorry if I make mistake in the schema representation):
Book {
name: String!
author: String!
categories: [String!]
}
How would I do a query for all books that are part of the "mystery"
category? I know I can filter with allBooks(filter: {})
, but categories_in: ["mystery"]
and categories_contains: "mystery"
didn't do the trick.
Category
modelThinking a bit more about this situation, creating a Category
model is definitely the way to go.
For example, imagine you want to allow readers to subscribe to their favorite categories later. Or, what if you want a list of all existing categories? Using string lists, you would need to query all books and somehow postprocess all obtained categories. Handling this on a model level rather than using string lists feels much more natural.
Instead, you can create a new Category
model and add a many-to-many relation between Category
and Book
. In situations like this, I like to add a unique enum field tag
and a string field text
. (A unique string field tag
alone would also be suitable, probably a matter of taste.)
With this setup, you can easily fulfill data requirements like
Which books are assigned to a given category?
query {
# query books by unique category tag
Category(tag: MYSTERY) {
books {
id
}
}
# query books by specific category text
Category(filter: {
text: "mystery"
}) {
books {
id
}
}
}
Which books are assigned to at least one category of a given list?
query {
allCategories(filter: {
OR: [{
tag: MYSTERY
}, {
tag: MAGIC
}]
}) {
books {
id
}
}
}
Which books are assigned to all categories of a given list?
query {
allCategories(filter: {
AND: [{
tag: MYSTERY
}, {
tag: MAGIC
}]
}) {
books {
id
}
}
}
Even though the above queries fulfill the specified data requirements, books are grouped by Category
in the response, meaning that we would have to flatten the groups on the client.
With so called related filters, we can turn that around to only obtain books based on conditions defined its related categories.
For example, to query books assigned to at least one category of a given list:
query {
allBooks(filter: {
OR: [{
categories_some: {
tag: MYSTERY
},
categories_some: {
tag: MAGIC
}
}]
}) {
id
}
}