2
votes

I'm moving my complex user database where users can be on one of many teams, be friends with each other and more to Neo4j. Doing this in a RDBMS was painful and slow, but is simple and blazing with Neo4j. :)

I was hoping there is a way to query for

  • a relationship that is 1 hop away and
  • another relationship that is 2 hops away

from the same query.

START n=node:myIndex(user='345')
MATCH n-[:IS_FRIEND|ON_TEAM*2]-m
RETURN DISTINCT m;

The reason is that users that are friends are one edge from each other, but users linked by teams are linked through that team node, so they are two edges away. This query does IS_FRIEND*2 and ON_TEAM*2, which gets teammates (yeah) and friends of friends (boo).

Is there a succinct way in Cypher to get both differing length relations in a single query?

2
Joseph, any chance you could do a small example on console.neo4j.org?Peter Neubauer

2 Answers

2
votes

I rewrote it to return a collection:

start person=node(1) 
match person-[:IS_FRIEND]-friend 
with person, collect(distinct friend) as friends 
match person-[:ON_TEAM*2]-teammate 
with person, friends, collect(distinct teammate) as teammates 
return person, friends + filter(dupcheck in teammates: not(dupcheck in friends)) as teammates_and_friends

http://console.neo4j.org/r/oo4dvx

thanks for putting together the sample db, Werner.

1
votes

I have created a small test database at http://console.neo4j.org/?id=sqyz7i

I have also created a query which will work as you described:

START n=node(1) 
MATCH n-[:IS_FRIEND]-m 
WITH collect(distinct id(m)) as a, n 
MATCH n-[:ON_TEAM*2]-m 
WITH collect(distinct id(m)) as b, a
START n=node(*) 
WHERE id(n) in a + b
RETURN n