How to find relationship between two nodes?

I have a practical case: end user need look up the relationships between 2 persons, like one is the other’s co-starring or 2nd wife in a knowledge graph for entertainment persons. Considering performance, we limit the depth up to 6.
Neo4j query is like:

MATCH (martin:Person { name: 'Martin Sheen' }),(oliver:Person { name: 'Oliver Stone' }), p = shortestPath((martin)-[*..6]-(oliver))
RETURN p

How does dgraph find the relationships within 6 hops?

Hey @catslink, I hope this might be useful to you https://dgraph.io/docs/query-language/#k-shortest-path-queries. Feel free to raise any follow-ups.

1 Like

In addition to Minhaj’s suggestion. You could also do this with Recurse Query. The only problem is that you need to hard type all possible edges (in shortest you have also to do this) to accomplish that. e.g:

{
	M as var(func: type(Person)) @filter(eq(name, 'Martin Sheen')
	O as var(func: type(Person)) @filter(eq(name, 'Oliver Stone')

	q(func: uid(O) @recurse(depth: 50, loop: true) {
		friend @filter(uid(M))
		~friend @filter(uid(M))
		follows @filter(uid(M))
		~follows @filter(uid(M))
	}
}

My idea would be to reduce this to:

{
	M as var(func: type(Person)) @filter(eq(name, 'Martin Sheen')
	O as var(func: type(Person)) @filter(eq(name, 'Oliver Stone')

	q(func: uid(O) @recurse(depth: 50, loop: true) {
		expand(User) @filter(uid(M))
	}
}

It would expand and apply the same filter to all edges. Today expand only supports Type filter.

I have created an issue for this

Thanks for your quick response, looking forward to the issue resolved, but expand cannot get shortest path, right?
Another question, if I want to find all predicates on shortest path between 2 nodes, I am wondering if this way could resolve hard typing problem: I create a new edge for each predicate, with fixed name like “fakedEdge” along with a facet “name” whose value is real predicate. Then use k-shortest path query to get all fakedEdge and its facet @facet(name).

{
  path as shortest(from: 0x2, to: 0x5) {
    fakedEdge @facet(name)
  }

  path(func: uid(path)) {
     name
  }
}

Also k-shortest path query or expand(User) @filter(uid(M)) is expected to support query by multiple nodes using func:eq(name, “aa”) as neo4j already supports, which is also useful in practice.

Nope, shortest path is a very unique type of query. You can’t do some things inside of it.

All predicates you can’t. You can find relationships on known edges. To find all predicates you have to use recurse with filters.

Not sure if I followed.

In brief, below feature is fully expected:
MATCH (martin:Person { name: ‘aa’ }),(oliver:Person { name: ‘bb’ }), p = shortestPath((martin)-[*…6]-(oliver))
RETURN p
it will return shortest paths between all persons whose name are “aa” or “bb”。 Not only one person has the name “aa”, it is usual that multiple persons have same name in some countries.

As to find all predicates on shortest path between 2 nodes, I think faked known edge will work, but not sure the performance is ok. I will try it later.

I tested fakeEdge doesn’t work, we can look up the fakeEdge with name “daughter” as 1.png, but shortest path cannot get it as 2.png. If remove returning@facets(name) in shortest path, the 2 nodes are returnend as 3.png.
Why??
1.png

2.png

3.png