Variable propagation in same query block

How to get the following query to work? I need to get the region uid under “workflow” to use as a variable for the location region. It doesn’t work as nothing is returned. If I hard code a location it works but wondering why the variable propagation doesn’t work here with the “reg” variable.

I also tried it with uid(val(reg)) and produces the same result.

{
  invoices(func: type(invoice), first: 5000) @cascade {
    purchase_orders {
      workflows: ~purchase_orders @filter(type(workflow)) {
        reg as regions
        locations {
          regions @filter(uid(reg))
          location_uid: uid
          location: location.name
        }
      }
    }
  }
}

Something like this?

{
  invoices(func: type(invoice), first: 5000) @cascade {
    purchase_orders {
      workflows: ~purchase_orders @filter(type(workflow)) {
        regions { reg as uid }
        locations {
          regions @filter(uid(reg))
          location_uid: uid
          location: location.name
        }
      }
    }
  }
}

Same issue unfortunately.

When you put the reg variable declaration in a separate query block, it works.

Data:
<_:reg1> <name> "Reg1" .
<_:reg2> <name> "Reg2" .

<_:node1> <name> "Node1" .
<_:node2> <name> "Node2" .
<_:node3> <name> "Node3" .

<_:node1> <child> <_:node2> .
<_:node1> <child> <_:node3> .
<_:node1> <reg> <_:reg1>.
<_:node2> <reg> <_:reg1>.
<_:node3> <reg> <_:reg2>.

Query:
{
  var(func: has(name)) @filter(eq(name, "Node1")) {
    name
    R as reg # works
  }
  q(func: has(name)) @filter(eq(name, "Node1")) @cascade {
    name
    #R as reg # doesn't work
    child {
      name
      reg @filter(uid(R))
    }
  }
}

I think both versions should work tho.

Ya the separate block works when you are doing a more global collection of regions. In my situation I need it to use the region underneath the workflow type for that specific workflow. So the region UID would be the region edge on its parent workflow.

I see. You’ll probably like my issue then, where I tried to do something similar. Nested / cyclic filtering not working

@chewxy @dmai any other suggestions I can try out to get this to work?

I have none for now. I’d check with @pawan and @MichelDiz as well

I think what you are looking for is local filtering along every path instead of one global filtering. I think it’s not possible currently to do that but I can confirm if you share a small example dataset, the query and the expected response?

I have this discussion Promise a nested block (under construction - I'm still working in the use case) which I have noted some use cases related to Variables in the same block. Dgraph won’t work well with variables in the same block and in different levels of the block if not an aggregation.

I think that is a huge work to analyze and make a decision on the design of the Query System. For now multiple blocks are the only way and can be tricky for some use cases. But I think two blocks for this case (of the topic itself) are acceptable. Something like:

{
  I as var(func: type(invoice), first: 5000) @cascade {
    purchase_orders {
      workflows: ~purchase_orders @filter(type(workflow)) {
        reg as regions { uid }
      }
    }
  }
    invoices(func: uid(I)) @cascade {
      purchase_orders {
        workflows: ~purchase_orders @filter(type(workflow)) {
          locations {
            regions @filter(uid(reg))
            location_uid: uid
            location: location.name
            }
          }
        }
    }
}

Also, internally I have this https://discuss.dgraph.io/t/improvement-on-the-query-system/8365

Hey @MichelDiz,

How would that work in a two block query if the variable should be from the corresponding parent workflow? Wouldn’t the “reg” variable just be a list of regions that occurred in the var block? Using the query you pasted above I get results that have this:

Whereas the location region should match the workflow region and if it doesn’t then it shouldn’t be included.

You right, I have just noticed that after writing - also I have noted that behave in my on old tests. The only way to “control” this collateral result is by using pagination (e.g q(func: type(Person), first:1) plus offset usage). Which isn’t good for your case.

Maybe we should have a new type of var that holds the values block to the next block or have loops. Or supporting the filtering in the same single block and levels of a single block.

Ya I think that would be the only way to satisfy this use case. In the meantime I can just loop through the results client-side and remove any non-matching locations.