Comparing two predicate counts in a filter

Trying to find all nodes that have the same number of uids in SecondList as they have in FirstList.

query {
  nodes(func:type("Node"))
    @filter(eq(count(FirstList), count(SecondList))
    @cascade
  {
    # FirstList {
    #   uid
    # }
    # SecondList {
    #  uid
    # }
  }
}

But there is an error from dgraph saying “Multiple functions as arguments not allowed”.

Is there some other way that this can be achieved?

Have you tried using variables to store the count result, and using it in the filter?

Sure, but it has the same problem since the eq function has two val() functions inside…

query {
  ID as var(func:type("Node")) {
    firstCount as count(Links @filter(type("Node")))
    secondCount as count(Links @filter(ge(count(Links),1)))
  }
  nodes(func:uid(ID))
      @filter(eq(val(firstCount), val(secondCount)))
  {
    uid
  }
}

Same error: Multiple functions as arguments not allowed.

None of those syntaxes doesn’t exists in Graphql+- as you can see in the docs https://docs.dgraph.io/query-language/#inequality

Try something like this

{
  var(func:type("Node"))  {
   F as  FirstList
   S as  SecondList
  }
  
  q(func: uid(F)) @filter(uid(S)) {
    uid
    expand(_all_)
  }
}

What gonna happen is, the query block will expand all nodes in FirstList, and then filter to show only those nodes that exists in both edges.

Assuming that:

FirstList has:
0x20
0x21
0x23
0x24
0x25
0x26

SecondList has:
0x21
0x23
0x25
0x26

The result for the query should be:

0x21
0x23
0x25
0x26

You can also use q(func: uid(F)) @filter(NOT uid(S))
The result for the query should be:

0x20
0x24

This is not quite the same thing as I asked. I don’t care about the actual nodes, I only care about the amount of nodes.

All I care is to find UIDs whose list lengths are the same, without caring about the content of these lists.

For example, given a genealogy tree find all people who have the same number of siblings as their number of children. Naturally their brothers and sisters are not the same people as their children. And the query would find people who have 4 siblings and 4 children, as well as those who only have 1 sibling and 1 child. But not those who have 3 siblings and 2 children, or 5 children but 1 sibling.

Hum, I was trying to accomplish what I understood from your queries. What the syntaxes would mean. But as you explained it better, I can see that the queries are far from it. And I can say that is not possible to do it in a practical way. Bellow follows a kind of “hack” way to do comparisons and getting a meaningful result from it (Like “true/false”).

It is “hacky”, which means it can’t have the desired result in other scenarios and it abuses from the query system.

I’ve used the other sample of yours to do this example.

{
  var(func: uid(0x7)) {
    A as count(Links) #It has 2 links
  }
  var(func: uid(0x6)) {
    B as count(Links) #It has 1 link
  }

  var() {
    G as sum(val(A))
    T as sum(val(B))
  }
  me() {
    result: math( G > T )
  }
}

Result

{
  "data": {
    "me": [
      {
        "result": true
      }
    ]
  }
}

And this needs a deeper look and thought to answer.