Variable not filtered by @cascade

Motivation

I’m trying to filter a list of jobs based on the user related through the managers field. While my top query is correctly filtered, the variable it creates is unfiltered.

I am going to create a secondary query to handle this filter, but it is unintuitive that cascade doesn’t limit the value of the variable.

Dgraph Version
v20.11.3 

Have you tried reproducing the issue with the latest release?

No, having problems starting the images since dgraph_ratel isn’t in $PATH.

What is the hardware spec (RAM, OS)?

16gb Ubuntu linux in docker.

Steps to reproduce the issue

With the query:

myJobs (func: type("Job")) @cascade {
  jobs as uid
  managers @filter(uid($manager)) {
    uid
  }
}
        
totalCount(func: uid(jobs)) {
  count(uid)
}

Expected behavior and actual result.

The jobs variable should have the same values as the myJobs query. Instead, I get the result:

"myJobs": [
  {
    "uid": "0x35",
    "managers": [
      {
        "uid": "0x15"
      }
    ]
  }
],
"totalCount": [
  {
    "count": 32
  }
],

I’ll look into your problem in a bit, but for now, given Ratel is not included in the Docker image, you can use play.dgraph.io.

  1. Click on the Dgraph logo:
    image
  2. Use your localhost address:
    image

Looking at your query, let me translate it into English:

  1. First find all nodes with the type “Job”, that only has managers and uid as predicates. (Cascade happens here)
  2. Filter all managers that match the given $manager variable
  3. Count the UIDs from step 1.

That makes sense, but only one Job has managers. The query

{
  myJobs (func: type("Job")) @cascade {
  jobs as uid
  managers @filter(uid($manager)) {
    uid
  }
}
        
  fiveJobs(func: uid(jobs), first: 5) {
    uid
    managers
  }
}

shows the result

    "myJobs": [
      {
        "uid": "0x35",
        "managers": [
          {
            "uid": "0x15"
          }
        ]
      }
    ],
    "fiveJobs": [
      {
        "uid": "0x16"
      },
      {
        "uid": "0x17"
      },
      {
        "uid": "0x18"
      },
      {
        "uid": "0x19"
      },
      {
        "uid": "0x1a"
      }
    ]

The jobs variable is getting the value of all jobs without respect to cascade, which as you pointed out, happens in step 1.

This looks like a bug a bit, have you tried the following?

EDIT PS. Forget what I said above, it’s not a bug. It is the other case. Cascade does not apply to other blocks directly.

{
  MG as (func: uid($manager))

  myJobs (func: type("Job")) @cascade {
  jobs as uid
  managers @filter(uid(MG)) {
    uid
  }
}
        
  fiveJobs(func: uid(jobs), first: 5) {
    uid
    managers
  }
}

BTW, a cascade function in one block, doesn’t necessary will affect the other block. Cascade is always applied in the root of the main block, not others.

I’m sure you can see how if it appears as a bug to you, it definitely feels like one to someone who is less familiar with dgraph. It doesn’t make sense intuitively that jobs can have more uids in it than the result of the myJobs query.

Edit:
This works as expected.

jobs as var(func: type("Job")) @cascade {
  managers @filter(uid($manager))
}

Thanks for your help.