Possible to count C per A if A connects to B connects to C?

I’m not sure the best way to explain this except by example. I have nodes of type A, B, and C.

  • As have a uid list predicate that contains nodes of type B
  • Bs have a uid predicate that contains nodes of type C

I want to know how many distinct As there are in my graph that transitively connect to Cs, and I want the uid of the Cs. I imagine there’s probably some way to build a query that uses value variables for this, and math(), but I haven’t figured it out yet. I’m on v21.03.0.

Example schema + data + query:

type A {
  b
}
b: [uid] @reverse .
type B {
  c
}
c: uid @reverse .
type C {
  somethingdoesntmatter
}
somethingdoesntmatter: string .
<0x1> <dgraph.type> "A" .
<0x1> <b> <0x3> .

<0x2> <dgraph.type> "A" .
<0x2> <b> <0x4> .

<0x3> <dgraph.type> "B" .
<0x3> <c> <0x5> .

<0x4> <dgraph.type> "B" .
<0x4> <c> <0x5> .

<0x5> <dgraph.type> "C" .
<0x6> <dgraph.type> "C" .
<0x7> <dgraph.type> "C" .

and in this example the output would tell me that there are two A nodes (just the count) that reference the one C node (the uid 0x5).

I have tried this:

query {
  foo(func: type(C)) {
    cuid: uid
    uid
    ~c {
      count(~b)
    }
  }
}

which returns roughly:

{
  "data": {
    "foo": [
      "cuid": "0x5",
      "~c": [
        {
          "count(~b)": 1
        },
        {
          "count(~b)": 1
        }
      ]
    ]
  }
}

I can sum up the “count(~b)” values in my client (values that will always be 1, FWIW) but that’s not scalable. If it instead returned "~c": 2 I’d be happy.

That’s not possible due to the 3 levels of difference. 1+1 level it should be okay. You should use some lambda with JS to get the result you want.

But see if this fits:

query {
  foo(func: type(C)) @cascade {
    cuid: uid
    uid
    ~c @normalize {
      G as count(~b)
    }    
     count :  sum(val(G))
  }

}

Thanks – I ended up adding a denormalized predicate that contained the list connecting A to C and have code to periodically validate that all Bs are in there.