# Limitations of GraphQL nested filters

**URL:** https://discuss.dgraph.io/t/limitations-of-graphql-nested-filters/10798
**Category:** GraphQL
**Tags:** ticket:created, kind:enhancement, status:accepted, graphql
**Created:** [October 6, 2020, 11:01am UTC](https://discuss.dgraph.io/t/limitations-of-graphql-nested-filters/10798 "2020-10-06T11:01:47Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![rajas](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/rajas/32/4393_2.png) [@rajas](https://discuss.dgraph.io/u/rajas)
#### Post date: [October 6, 2020, 11:01am UTC](https://discuss.dgraph.io/t/limitations-of-graphql-nested-filters/10798/1 "2020-10-06T11:01:47Z")

</div>

## 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:

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

```

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

```auto
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:

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

```

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

```auto
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.

```auto
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. [Complex GraphQL Filtering | GRANDstack](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](https://hasura.io/docs/1.0/graphql/core/queries/query-filters.html#using-multiple-filters-in-the-same-query-and-or)
3. [Functional completeness - Wikipedia](https://en.wikipedia.org/wiki/Functional_completeness)

---

<div class="post-metadata">

### Author: ![amaster507](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/amaster507/32/4123_2.png) [@amaster507](https://discuss.dgraph.io/u/amaster507)
#### Post date: [October 6, 2020, 12:34pm UTC](https://discuss.dgraph.io/t/limitations-of-graphql-nested-filters/10798/2 "2020-10-06T12:34:12Z")

</div>

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

---

<div class="post-metadata">

### Author: ![michaelcompton](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/michaelcompton/32/1774_2.png) [@michaelcompton](https://discuss.dgraph.io/u/michaelcompton)
#### Post date: [October 6, 2020, 11:34pm UTC](https://discuss.dgraph.io/t/limitations-of-graphql-nested-filters/10798/3 "2020-10-06T23:34:39Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![pawan](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/pawan/32/1946_2.png) [@pawan](https://discuss.dgraph.io/u/pawan)
#### Post date: [October 7, 2020, 12:32pm UTC](https://discuss.dgraph.io/t/limitations-of-graphql-nested-filters/10798/5 "2020-10-07T12:32:45Z")

</div>

> [@michaelcompton](#):
>
> 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.

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?

---

<div class="post-metadata">

### Author: ![pawan](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/pawan/32/1946_2.png) [@pawan](https://discuss.dgraph.io/u/pawan)
#### Post date: [October 9, 2020, 10:11am UTC](https://discuss.dgraph.io/t/limitations-of-graphql-nested-filters/10798/6 "2020-10-09T10:11:25Z")

</div>

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?

---

<div class="post-metadata">

### Author: ![gja](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/gja/32/2654_2.png) [@gja](https://discuss.dgraph.io/u/gja)
#### Post date: [October 9, 2020, 2:28pm UTC](https://discuss.dgraph.io/t/limitations-of-graphql-nested-filters/10798/7 "2020-10-09T14:28:09Z")

</div>

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

---

<div class="post-metadata">

### Author: ![amaster507](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/amaster507/32/4123_2.png) [@amaster507](https://discuss.dgraph.io/u/amaster507)
#### Post date: [October 9, 2020, 5:13pm UTC](https://discuss.dgraph.io/t/limitations-of-graphql-nested-filters/10798/8 "2020-10-09T17:13:02Z")

</div>

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:

> [@There can be only one input field named \*](http://discuss.hypermode.com/t/there-can-be-only-one-input-field-named/8384/4):
>
> What I would expect after working with and/or logic in the auth directive is for it to work almost the same way with arrays with the first and being understood. I understand this would be a breaking change because there is no way to right GraphQL schema where a filter can be either an object or an array so filter: {title: {...}} would no longer work if this is implemented These two queries would be equivalent: # with understood `and` query example1 { queryPost(filter: [ {title: {allofte…

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