Behavior of cascade not clear with aggregation

Moved from GitHub dgraph/4024

Posted by animesh2049:

What version of Dgraph are you using?

version: 5b20d411f7cb21fe575503e70f60ca48bb794bb1

Steps to reproduce the issue and expected behaviour and actual result.

Behavior of aggregators is not clear when used with @cascade.
Data:

_:animesh <name> "Animesh" .
_:ashish <name> "Ashish" .
_:aman <name> "Aman" .
_:prashant <name> "Prashant" .

_:animesh <age> "24" .
_:ashish <age> "27" .
_:aman <age> "26" .

_:animesh <friend> _:ashish .
_:ashish <friend> _:aman .
_:aman <friend> _:prashant .

query:

{
  var(func: has(name)) @cascade {
    friend {
      age_var as age
      friend {
        age
      }
    }
  }
  me() {
    min(val(age_var))
  }
}

Response:

{
  "data": {
    "me": [
      {
        "min(val(age))": 26
      }
    ]
  },
  "extensions": {
    "server_latency": {
      "parsing_ns": 28933,
      "processing_ns": 7890307,
      "encoding_ns": 5757,
      "assign_timestamp_ns": 652749
    },
    "txn": {
      "start_ts": 154
    }
  }
}

age_var should only contain those nodes, whose friend's have age and friend's friend have age. Here root query will have uids of animesh, ashish, aman, prashant,

animesh --(friend)----> ashish (name: "Ashish", age(aliased as age): 27) --(friend)--> aman (name: "Aman", age: 26)
ashish --(friend)--> aman (name: "Aman", age(aliased as age): 26) --(friend)--> prashant(name: "Prashant") # Prashant doesn't have age so this should be filtered out due to cascade
aman --(friend)--> prashant(name: "Prashant") # This should also be filtered 
prashant # This should also be filtered

So age_var should only have uid of ashish and min(val(age)) should be 27, but we are getting 26 which is aman's age.
Right now it seems @cascade is being ignored.

insanitybit commented :

I’d like to suggest this as a feature. This greatly complicates queries for me, and is really unintuitive. I’ve had a long standing bug in my project because of my assumption that cascade was impacting the results of var queries.

Here is one example I have for my own project.

This is the ‘expected’ (no-cascade version)

It’s also unintuitive that cascade would behave differently at all in a var block vs a query block, and that it is effectively silently dropped today is even less of an expected behavior.

Note that there’s nothing in the documentation about this difference either.

edit: It is actually not silently dropped. Cascade definitely impacts var blocks, I’m just unsure of the semantics. It seems to work only on the structure/properties, not on filters?

MiLeung commented :

I still have this issue. The way I work around it is I have to do something like this

settings {
  notifications @filter(eq(whenSomeonePosts, true)) {
    # traversing back and forth cuz cascading here doesn't filter UIDs here
    ~notifications {
      ~settings {
        peers as uid
      }
    }
  }
}

but the issue is you have to add more @reverses to your schema in order to make it work.