Limitations of GraphQL nested filters

Current Solution for Filters in GraphQL

Currently, Dgraph GraphQL has the functionality to take input of filter in query<type_name> type queries. Nodes which satisfy the criteria specified in the filter are only considered in the query and other nodes are filtered out. Example:

queryPost(filter: { text: { alloftext: "foobar" } } ) 

Boolean operators like and , or and not are also supported inside filters.
Example:

queryPost(filter: { text: { alloftext: "foobar" } }, or: { score: { ge: 10 } } ) 

The input type <type_name>Filter in output GraphQL schema contains fields on which filters can be applied. It currently contains the fields with search directive along with and, or, not operators. Example:

type Author {
	id: ID!
	name: String!
}

The above input GraphQL schema generates the following AuthorFilter input type in output GraphQL schema.

input AuthorFilter {
	id: [ID!]
	has: AuthorHasFilter
	and: AuthorFilter
	or: AuthorFilter
	not: AuthorFilter
}

With the current functionality, it is possible to compound filters using boolean operators of the form A AND B , A OR B, NOT A etc.

Problem with Nesting Filters

But, because and and or fields inside AuthorFilter input type take only a single AuthorFilter instead of an array, [AuthorFilter], it is impossible to have a filter query of the form, (A OR B) AND (C OR D)

Proposed Solution to handle Nested Filters

Boolean operators AND and OR are binary operators and operate on atleast two operands. If the generated output schema for AuthorFilter is changed to have a list of AuthorFilter or two operands of the type AuthorFilter , it could then be possible to create any type of nested filters with AND and OR boolean operators. The changed input type of AuthorFilter will then look like.

input AuthorFilter {
	id: [ID!]
	has: AuthorHasFilter
	and: [AuthorFilter]
	or: [AuthorFilter]
	not: AuthorFilter
}

The proposed solution will change how AND and OR operators are used in filters. This will be a breaking change. This approach is also consistent with other GraphQL providers.

References

  1. https://grandstack.io/docs/graphql-filtering/#logical-operators-and-or
  2. https://hasura.io/docs/1.0/graphql/core/queries/query-filters.html#using-multiple-filters-in-the-same-query-and-or
  3. https://en.wikipedia.org/wiki/Functional_completeness
1 Like

This will also help clarify the order of operations with mixed conjunctions. Thank you!

We’ve been here before. We should just do it.

Personally, think the cost of keeping something that’s confusing is probably worse than the cost of a breaking change here … but it’s also possible to add the list alternative, and deprecate an later remove the orriginal.

3 Likes

Agree, we should just go ahead and do this as part of 20.11. Whether we should make this a breaking change or add alternate fields (ands , ors) and later deprecate the old fields would depend on how Slash plans to handle upgrading users as well. Users who are already using Slash would now have to modify their queries for their App to keep on working if its a breaking change. What do you think about this @gja?

1 Like

I think we should make a breaking change here and just go ahead with this change. I don’t want to introduce fields named ands and ors because then we won’t be able to change them later. Let’s just make the current fields accept arrays. It should be easy for users to fix their code to incorporate this change. Does that sound ok @vvbalaji?

Please don’t make this a breaking change. Making breaking changes to the query language is simply a bad user experience. Think of mobile apps which are out in the wild that use your GraphQL endpoint. You will have consumers who are using that for years before they have the chance to upgrade.

Breaking File System Compatibilty is bad, but we can manage with scripts, as it’s in our control
Breaking Schema Compatibility is worse. Users might suddenly wake up one day and find their backend non responsive. At a slash level, somehow we can maybe do this occasionally.
Breaking Query Language is catastrophic. You have no control over how many clients use it. There is no remedy here.

@pawan

There will be breaking changes inevitably. This needs to be discussed as to how it is handled and how slash endpoints are updated to the breaking changes. @gja we discussed this before on here somewhere

EDIT: Here was the related post about this same issue and breaking and/or into arrays:

I also found the conversation about how breaking changes will be handled, that was in a private message.