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
name | mutualGroups | mutualFriends |
---|---|---|
2 rows | ||
|
|
|
|
|
|
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