DQL query to find nodes with given list of links

Lets say i have the following types with n to n links:

type Cart {
  id: ID!
  items: [Item] @hasInverse(field: inCarts)
type Item {
  id: ID!
  inCarts: [Cart]

Now i have a defined list of ids of items.

Is it possible to find all carts which contain this exact list of items (or more) with a DQL query?

Sort of example query:

var(func: type(Item)) @filter(some filter) {
  items as uid <-- the list of items
q(func: type(Cart)) @filter(filter to only fetch Carts with given list of items or more) {


Hi @LCL,

Have you checked out the uid_in function? https://dgraph.io/docs/query-language/functions/#uid_in

I think you’ve got to know the size of the list and do a query per item. For efficiency I’d come down from one of the items to start.

item1 as var(func:type(Item),first:1) @filter(..)
item2 as var(func:type(Item),first:1,offset:1) @filter(..)
item3 as var(func:type(Item),first:1,offset:2) @filter(..) {
  carts as inCarts
    ge(count(items),3) and
    uid_in(items,uid(item1)) and

carts(func:uid(carts)) { uid }

If you wanted a precise match you could match the exact length instead: eq(count(items),3)

I’m curious to see if anyone comes up with a dynamic way to do it. Some kind of “match all” function for query variables would be nice.

items as var(func:type(Item)) @filter(..)

{ uid }
1 Like

Try to keep the ineficient type functions out of root as much as possible. The pagination will not produce the expected results here if pagination on all blocks like your example. If the intention of the blocks is to reduce the universe then at all possible start the next block with the smallest universe possible like for item2, use uid(item1) for the root

The pagination works. If you have a list of 3 items, it selects each of them.

item1(func:eq(ListItem.name,"list1"),first:1) { uid }
item2(func:eq(ListItem.name,"list1"),first:1,offset:1) { uid }
item3(func:eq(ListItem.name,"list1"),first:1,offset:2) { uid }
    "item1": [{ "uid": "0x361b11" }],
    "item2": [{ "uid": "0x361b12" }],
    "item3": [{ "uid": "0x361b13" }]

Thanks for the responses @matthewmcneely, @amaster507, @RivenAster!

Let me refine the example a bit.


type Cart {
  id: ID!
  items: [Item] @hasInverse(field: inCarts)
type Item {
  id: ID!
  name: String! @search(by: [exact, regexp, term])
  inCarts: [Cart]

Given is a filter for Item.name called itemFilter. This filter results in n items → the amount of matching items is unknown, can be 0, can be 20. Lets call this list filteredItems.

What I want to query is the carts which contain filteredItems as a subset of Cart.items.

All of this should happen in one query.

Thanks in advance!

Are there any updates on this?