0
votes

I'm new to Cypher and am trying to figure out how to exclude nodes from a query under certain circumstances.

The graph consists of friends ( me-[friend]-person ) and friend-of-friend relationships ( me-[fof]-person )

I need to find all friend of friend relationships (easy enough), but exclude those friends of friends who are also 'friends'

I thought I could do :

START me=node(0)           
MATCH me-[r:fof]->fof, me-[f?:friend]->fof           
WHERE f is null and NOT(r is null)
and ... [other filters]

But this seems like the wrong way to go about getting Friends of Friends who are NOT also friends.

Suggestions?

3

3 Answers

9
votes

You can filter based on existing relationships in the WHERE clause, and of course you can use NOT to negate any condition:

START me=node(0)           
MATCH me-[r:fof]->fof
WHERE NOT(me-[:friend]->fof)
and ... [other filters]
3
votes

Why use two relation types: friend and fof? You could model the entire friend graph using one relation i.e. friend and then filter by depth like MATCH (me)-[:friend*2..]->(friend) which is friends of friends any level deep or MATCH (me)-[:friend*2..2]->(friend) for just friends of friends

0
votes

this is just an info answer, since the answer has been already provided by @ean5533.

if the speed really matters, you can try to create a new relationship type fof2 for all cases, where you are really a friend of friend but not direct friend:

start n=node(*) 
match n-[:fof]-friend
where not(n-[:friend]-friend)
create unique n-[:fof2]-friend;

than querying the real strange friend of friend would be faster with:

start n=node(0)
match p=n-[:fof2]-friend
return p;