Easier way to check if a node is connected to all nodes in a set

Moved from GitHub dgraph/4544

Posted by martinmr:

Experience Report

What you wanted to do

User wanted to get all the nodes that have ALL the edges to specific nodes. Filter does not work because it returns nodes that have any of the edges.

What you actually did

It’s possible to do this but the resulting query ended up being very complicated and does not scale well with the number of objects to check.

Why that wasn’t great, with examples_

Here’s the resulting query.


  # Get Datasets with population_attribute_value with system_id "d".
  # @cascade removes any Dataset object that does not have a value for
  # population_attribute_values.
  A as var(func: type(Dataset)) @cascade
{
    uid
    population_attribute_values @filter(eq(system_id, "d")) {
    uid
    }
  }
    
    
  # Get Datasets with population_attribute_value with system_id "e".
  # Only consider elements from the previous query.
  B as var(func: uid(A)) @cascade
{
    uid
    population_attribute_values @filter(eq(system_id, "e")) {
    uid
    }
  }
    
  # Get Datasets with population_attribute_value with system_id "f".
  # Only consider elements from the previous query.
  C as var(func: uid(B)) @cascade
{
    uid
    population_attribute_values @filter(eq(system_id, "f")) {
    uid
    }
  }
    
  # C is the set of Dataset objects that have the three
  # population_attribute_values objects needed.
  q(func: uid(C)) {
    uid
    # The filter needs to be here as well so that no additional
    # population_attribute_values are shown. If you just want the
    # uids of the dataset objects you could remove this block.
    population_attribute_values @filter(eq(system_id, ["d", "e", "f"])) {
      uid
    }
  }
}

Any external references to support your case