# GraphQL: Connected filter on non-scalar list element fields

**URL:** <https://discuss.dgraph.io/t/graphql-connected-filter-on-non-scalar-list-element-fields/11581>\
**Category:** GraphQL\
**Created:** [November 23, 2020, 1:35am UTC](https://discuss.dgraph.io/t/graphql-connected-filter-on-non-scalar-list-element-fields/11581 "2020-11-23T01:35:29Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![CosmicPangolin1](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/cosmicpangolin1/32/3579_2.png) [@CosmicPangolin1](https://discuss.dgraph.io/u/CosmicPangolin1)\
**Post date:** [November 23, 2020, 1:35am UTC](https://discuss.dgraph.io/t/graphql-connected-filter-on-non-scalar-list-element-fields/11581/1 "2020-11-23T01:35:29Z")

</div>

Consider the following schema:

```auto
type User {
   posts: [Post!] 
}

type Post {
   content: String!
   reactions: [Reaction!]
}

type Reaction {
   type: String!
   user: User!
}

```

I want to query for a user and filter for his/her posts where the reaction list contains at least a reaction of type “thumbs\_up” AND a reaction of type “clap”, such that I receive the full list of reactions for posts that match this nested filter (ie. cascading with a filter on reaction type does not work).

This is likely relate closely to - and might be resolved by - the following proposals, but I’m not positive…(@chewxy?)

> [@Proposal: more filter functions](http://discuss.hypermode.com/t/proposal-more-filter-functions/10359):
>
> I propose we have the following filter functions: in - is a value of T in a [T] intersect - what is the value of a [T] when intersected with a [T] The first feature can be of course emulated by anyofterms . The latter however, requires a lot more work. An example is in a many-to-many relations: type Post { cat: [Cat]! content: String! } type Cat { posts: [Post] @hasInverse(field: cat) } type Interest { name: String! categories: [Cat]! } So if you want to get all P…

> [@Filter on non-scalar fields or relations (Types)](http://discuss.hypermode.com/t/filter-on-non-scalar-fields-or-relations-types/10292/14):
>
> Hi! Are there any news on this issue? I feel like this is an super-important and often-used feature. We would use it heavily in our software.

There are other list filters that would be immediately useful to me as well…length primarily.

---

<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:** [November 23, 2020, 3:36am UTC](https://discuss.dgraph.io/t/graphql-connected-filter-on-non-scalar-list-element-fields/11581/2 "2020-11-23T03:36:39Z")

</div>

I agree with you that this is something that cannot currently be done in a single query with GraphQL. The cascade directive does not solve this use case because you are wanting a AND filter on a child and cascade would only make sure that there is a child not that there are children of each type. A way around this in GraphQL currently would be to use cascade with alias edges. Create an alias for each child that must be included.

However, we currently solve this problem with filtering using deep logic by using DQL ([New to DQL?](http://discuss.hypermode.com/t/new-to-dgraph-dql-vs-graphql-endpoints-headers-and-schema-translation/10443)). With DQL, we can create multiple var blocks and then use logic to get resulting nodes by mixing those var blocks.

---

<div class="post-metadata">

**Author:** ![maaft](https://avatars.discourse-cdn.com/v4/letter/m/4af34b/32.png) [@maaft](https://discuss.dgraph.io/u/maaft)\
**Post date:** [November 23, 2020, 7:57am UTC](https://discuss.dgraph.io/t/graphql-connected-filter-on-non-scalar-list-element-fields/11581/3 "2020-11-23T07:57:22Z")

</div>

> [@amaster507](#):
>
> However, we currently solve this problem with filtering using deep logic by using DQL ([New to DQL?](http://discuss.hypermode.com/t/new-to-dgraph-dql-vs-graphql-endpoints-headers-and-schema-translation/10443)). With DQL, we can create multiple var blocks and then use logic to get resulting nodes by mixing those var blocks.

Isn’t @auth still a problem with DQL?

---

<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:** [November 23, 2020, 8:01am UTC](https://discuss.dgraph.io/t/graphql-connected-filter-on-non-scalar-list-element-fields/11581/4 "2020-11-23T08:01:53Z")

</div>

If by problem you mean that the @auth directive is not supported in DQL and all auth rules are completely ignored when running DQL queries and mutations, then yes.

Our work around for this is to use DQL to get a list of uids that fullfill the filter parameters and then with those uids, get the data using GraphQL.

When there is a will, there is a way 😉 I am all for making my work arounds not needed, but it is just how we learned to cope with some of the limitations in the meantime.

---

<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:** [December 10, 2020, 8:09am UTC](https://discuss.dgraph.io/t/graphql-connected-filter-on-non-scalar-list-element-fields/11581/6 "2020-12-10T08:09:00Z")

</div>

Hey @CosmicPangolin1

While we are looking into how could we make this possible, can you share an example of what result do you expect given a dataset? We can possibly look into supporting this in the next quarter once we know what you are looking for?

---

<div class="post-metadata">

**Author:** ![CosmicPangolin1](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/cosmicpangolin1/32/3579_2.png) [@CosmicPangolin1](https://discuss.dgraph.io/u/CosmicPangolin1)\
**Post date:** [January 10, 2021, 12:00am UTC](https://discuss.dgraph.io/t/graphql-connected-filter-on-non-scalar-list-element-fields/11581/7 "2021-01-10T00:00:31Z")

</div>

@pawan Sorry about the delay…I might be able to best illustrate with query examples (which may or may not be accurate in their own right, so correct me if need be).

**Query 1**

```auto
getUser {
   posts @cascade {
      content
      reactions(filter: {
         type: {in: ["thumbs_up", "clap"]}
      }){
         type
         user {name}
      }
   }
}

```

I think this query gets me only posts that have either thumbs up OR clap reactions. I believe it also sorts out reactions that don’t match the filter.

**Query 2**

```auto
getUser {
   posts @cascade {
      content
      reactions(filter: {type: {eq: "thumbs_up"}}, or: {type: {eq: "clap"}}) {
         type
         user {name}
      }
   }
}

```

I think this query gets me the same thing as the first.

**Query 3**

```auto
getUser {
   posts @cascade {
      content
      reactions(filter: {type: {eq: "thumbs_up"}}, and: {type: {eq: "clap"}}) {
         type
         user {name}
      }
   }
}

```

This wouldn’t return anything since the rules are mutually exclusive (as are the values).

So what I want is (I think) is a new input type on connected sets for contains/includes functionality, so I can build a query similar to Query 1 in that it filters for posts with thumbs\_up AND/OR clap reactions, but additionally returns all reactions.

The idea is that we often want to have cascading filters on computed properties of a connected set (contains, length, and every are the generic List methods that come to mind), the same way we do for values of singular fields. In my use case, I might have many posts with claps and many posts with thumbs\_ups, but only a few with both that I want to retrieve for a client. The functionally equivalent block would be something like:

```auto
if (arr.contains((reaction) => reaction.type == "clap") && arr.contains((reaction) => reaction.type == "thumbs_up")) {
   return arr;
}

```

It might look something like this:

```auto
getUser {
   posts @cascade {
      content
      reactions(contains: {type: {eq: "thumbs_up"}}, 
         and/or: {contains: {type: {eq: "clap"}}}
      ) {
         type
         user {name}
      }
   }
}

```

---

<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:** [January 21, 2021, 11:59am UTC](https://discuss.dgraph.io/t/graphql-connected-filter-on-non-scalar-list-element-fields/11581/8 "2021-01-21T11:59:55Z")

</div>

Hey @CosmicPangolin1

Can you please share a small data set on which I can run this query and the JSON result that you expect this query to run? I think what you are asking for is possible (by Query 3 you mentioned above) but maybe I am missing something.

---

<div class="post-metadata">

**Author:** ![CosmicPangolin1](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/cosmicpangolin1/32/3579_2.png) [@CosmicPangolin1](https://discuss.dgraph.io/u/CosmicPangolin1)\
**Post date:** [February 11, 2021, 10:19pm UTC](https://discuss.dgraph.io/t/graphql-connected-filter-on-non-scalar-list-element-fields/11581/9 "2021-02-11T22:19:36Z")

</div>

@pawan I want to make sure you got my private message with the details you’ve requested.

---

<div class="post-metadata">

**Author:** ![verneleem](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/verneleem/32/5801_2.png) [@verneleem](https://discuss.dgraph.io/u/verneleem)\
**Post date:** [February 12, 2021, 3:05am UTC](https://discuss.dgraph.io/t/graphql-connected-filter-on-non-scalar-list-element-fields/11581/10 "2021-02-12T03:05:11Z")

</div>

@CosmicPangolin1 see if this does what you are looking for. I have not tested this, and is dependent on cascade working with aliased fields, which I am not confident it does.

```auto
query {
  getUser( ... need an id of some sort here ... ) {
     posts @cascade(fields:["thumbs_up","clap"]) {
        content
        thumbs_up: reactions(filter: {
           type: {eq: "thumbs_up" }
        }) @cascade {
           type
        }
        clap: reactions(filter: {
           type: {eq: "clap" }
        }) @cascade {
           type
        }
        reactions {
          type
          user { name }
        }
     }
  }
}

```

If this works, here is the explanation: We add two additional aliased edges for reactions. These can be ignored by the client, but they are dependent for the top level cascade to work. In these aliased edges, we ask for all of the thumb up reactions in one, and all of the clap reactions in the other. Now all we have to do is use cascade at the post level to filter out the posts that do not have both a thumbs up and a clap. Then we add another edge to reactions to get all of the reactions regardless of the type. The cascade on the aliased edges are to reset the parameterized cascade on these edges so that it is still not filtering out ones reactions that don’t have a thumbs\_up and clap fields, which reactions doesn’t have.

If you know that all reactions will have a user and all users will have a name, and you are not getting any more information from the user besides his post at the top level, then you can instead just use a non parameterized cascade at the top level beside getUser.

```auto
query {
  getUser( ... need an id of some sort here ... ) @cascade {
    posts {
      content
      thumbs_up: reactions(filter: {
        type: {eq: "thumbs_up" }
      }) {
        type
      }
      clap: reactions(filter: {
        type: {eq: "clap" }
      }) {
        type
      }
      reactions {
        type
        user { name }
      }
    }
  }
}

```

Oh, and be sure to add in the id filter for getUser. Your initial schema in the OP is invalid with this query though, because there is not any ID or @id field for User, this would not generate the getUser query. Also User does not have a name field. I will assume that it was a partial schema only and not your actual schema.

---

<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:** [February 12, 2021, 3:19am UTC](https://discuss.dgraph.io/t/graphql-connected-filter-on-non-scalar-list-element-fields/11581/11 "2021-02-12T03:19:28Z")

</div>

Hey @CosmicPangolin1 I did and sorry it took long to reply to this. I’ll get this looked at in a couple of days for you.

---

<div class="post-metadata">

**Author:** ![JatinDevDG](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/jatindevdg/32/3417_2.png) [@JatinDevDG](https://discuss.dgraph.io/u/JatinDevDG)\
**Post date:** [April 21, 2021, 4:41am UTC](https://discuss.dgraph.io/t/graphql-connected-filter-on-non-scalar-list-element-fields/11581/12 "2021-04-21T04:41:40Z")

</div>

Hi sorry, for thje late reply. I just saw this while going over the old posts related to nested filters.

> [@verneleem](#):
>
> ```auto
> query {
> getUser( ... need an id of some sort here ... ) @cascade {
> posts {
> content
> thumbs_up: reactions(filter: {
> type: {eq: "thumbs_up" }
> }) {
> type
> }
> clap: reactions(filter: {
> type: {eq: "clap" }
> }) {
> type
> }
> reactions {
> type
> user { name }
> }
> }
> }
> }
> 
> ```

It’s not possible since Aliases are not allowed inside @cascade, you can only use original field names.
