How to get a node if and only if any related node, at an arbitrary number of hops, satisfies some property

Hello Community!

I am fairly new to DGraph, however I had quite some experience in other Graph databases like Neo4j.

While in Neo4j I can write queries like below to get a node based on related nodes at arbitrary depth, I couldn’t find a way to write similar kind of query in GraphQL or DQL.

MATCH (p)-[:Child*]->(q) WHERE q.name CONTAINS 'boss' RETURN p

I went through docs and various discussion threads, but couldn’t find one that can solve my use case.

It would be really helpful, if anyone can provide a solution or an approach to proceed.

The logic behind this query sounds quite odd but see below something that might work.

{
  var(func: eq(name, 'boss')) {
     Q as <~Child>
  }
    
  data(func: uid(Q)) {
    uid
  }
}

For more Cypher to DQL see

This in Dgraph is quite complicated.

By logic it would be something like

{
  var(func: has(Child)) @filter(has(<~Child>)){
     p as uid
     q as Child
  }
    
  data_p(func: uid(p)) {
    uid
  }
  data_q(func: uid(q)) {
    uid
  }
}

But in a Dgraph perspective this is odd and very expensive to do and you have to use reverse edges indexing. Dgraph is very different from Neo4j.

I wonder if you could do this in reverse using expand? Just an idea/theory though. Can you use a expand edges as a var?

{
  var(func: eq(name,"boss")) {
    A as expand(_all_) {
      B as expand(_all_) {
        C as expand(_all_) #more depth as needed??
      }
    }
  }
  p(func: uid(A,B,C)) {
    expand(_all_)
  }
}

Not sure, never thought about it. But I guess no.

But you could do a A as uid, etc. Inside each expand and then use those. Idk, just seemed like an interesting graph problem