GraphQL: filter data in an array

I am sure this is a simple thing, but I could not find anything in either the GraphQL document or Graphcool.

Let's say I have an entity with this schema (new GraphQL user, sorry if I am mistaken in the representation of the schema):

Book { name: String! author: String! categories: [String!] } 

How can I run a query for all books in the "mystery" category? I know that I can filter using allBooks(filter: {}) , but categories_in: ["mystery"] and categories_contains: "mystery" did not do the trick.

+6
source share
2 answers

Category model

Thinking a little about this situation, creating a Category model is definitely the way to go.

For example, imagine that you want users to subscribe to their favorite categories later. Or if you need a list of all existing categories? Using string lists, you will need to query all the books and somehow process all the categories received. Handling this at the model level, rather than using string lists, looks much more natural.

Instead, you can create a new Category model and add a many-to-many relationship between Category and Book . In situations like this, I like to add a unique tag enumeration field and a text string field. (A single string tag field in itself would also probably be a matter of taste.)

With this setting, you can easily fulfill data requirements, such as

Which books are assigned to a particular 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 in this list?

 query { allCategories(filter: { OR: [{ tag: MYSTERY }, { tag: MAGIC }] }) { books { id } } } 

What books are assigned to all categories in this list?

 query { allCategories(filter: { AND: [{ tag: MYSTERY }, { tag: MAGIC }] }) { books { id } } } 

Related Filters

Despite the fact that the above queries correspond to the specified data requirements, the books are grouped by Category in the response, which means that we will have to smooth out the groups on the client.

With so-called related filters, we can turn around so that we get books only on the basis of the conditions that determine the categories associated with them.

For example, to request books assigned to at least one category in this list :

 query { allBooks(filter: { OR: [{ categories_some: { tag: MYSTERY }, categories_some: { tag: MAGIC } }] }) { id } } 
+9
source

If you are interested in using the hosted GraphQL service, scaphold.io , this feature has appeared for a while. All connection fields in your API come with an WhereArgs argument, which provides filters that allow you to really embed your data. When you have a list of such scalars, WhereArgs has a contains and notContains field that allows you to filter the results based on the values ​​in your list. This allows you to make such a request.

 query MysteriousBooks($where:BookWhereArgs) { viewer { allBooks(where:$where) { edges { node { title, ... } } } } } # Variables { "where": { "categories": { "contains": "mystery" } } } 

To be complete, you can also do a small adjustment to the schema to make this work without having to filter the scalar list. For example, you can create a Category a node implementation type, and then create a connection between Category and Book . Although Book will probably not have many categories, this will allow you to issue this request:

 query MysteriousBooks($where: CategoryWhereArgs) { viewer { allCategories(where: $where) { books { edges { node { title, ... } } } } } } # Variables { "where": { "name": { "eq": "mystery" } } } 

If you structure your schema this way, you can also do more filtering on books in a category without having to go through each book in your archive. EG. you could effectively ask "all the secret books written last year."

Full disclosure: I work at Scaphold, and although I would like you to not have any difficulties if you don't switch. I am glad to see people who try and love GraphQL. If you are interested in how to implement this type of behavior on your own server, let me know and I will be happy to help there!

Hope this helps!

0
source

Source: https://habr.com/ru/post/1013846/


All Articles