6.6. Find people based on mutual friends and groups

Figure 6.6. Graph

In this scenario, the problem is to determine mutual friends and groups, if any, between persons. If no mutual groups or friends are found, there should be a 0 returned.

Query 

MATCH (me { name: 'Joe' }),(other)
WHERE other.name IN ['Jill', 'Bob']
OPTIONAL MATCH pGroups=(me)-[:member_of_group]->(mg)<-[:member_of_group]-(other)
OPTIONAL MATCH pMutualFriends=(me)-[:knows]->(mf)<-[:knows]-(other)
RETURN other.name AS name, count(DISTINCT pGroups) AS mutualGroups,
  count(DISTINCT pMutualFriends) AS mutualFriends
ORDER BY mutualFriends DESC

The question we are asking is — how many unique paths are there between me and Jill, the paths being common group memberships, and common friends. If the paths are mandatory, no results will be returned if me and Bob lack any common friends, and we don’t want that. To make a path optional, you have to make at least one of it’s relationships optional. That makes the whole path optional.

Result

namemutualGroupsmutualFriends
2 rows

"Jill"

1

1

"Bob"

1

0

Try this query live create (_0 {`name`:"Group1"}) create (_1 {`name`:"Joe"}) create (_2 {`name`:"Bob"}) create (_3 {`name`:"Bill"}) create (_4 {`name`:"Jill"}) create (_1)-[:`knows`]->(_3) create (_1)-[:`member_of_group`]->(_0) create (_2)-[:`member_of_group`]->(_0) create (_3)-[:`member_of_group`]->(_0) create (_4)-[:`knows`]->(_3) create (_4)-[:`member_of_group`]->(_0) ; MATCH (me {name: 'Joe'}), (other) WHERE other.name IN ['Jill', 'Bob'] OPTIONAL MATCH pGroups=(me)-[:member_of_group]->(mg)<-[:member_of_group]-(other) OPTIONAL MATCH pMutualFriends=(me)-[:knows]->(mf)<-[:knows]-(other) RETURN other.name as name, count(distinct pGroups) AS mutualGroups, count(distinct pMutualFriends) AS mutualFriends ORDER BY mutualFriends DESC