0
votes

NOT RELEVANT - SKIP TO Important Edit.

I have the following query:

MATCH (n)
WHERE (n:person) AND n.id in ['af97ab48544b'] // id is our system identifier
OPTIONAL MATCH (n)-[r:friend|connected|owner]-(m)
WHERE (m:person OR m:dog OR m:cat)
RETURN n,r,m

This query returns all the persons, dogs and cats that have a relationship with a specific person. I would like to turn it over to receive all the nodes & relationships that NOT includes in this query results.

If it was SQL it would be

select * from graph where id NOT IN (my_query)

I think that the OPTIONAL MATCH is the problematic part. I How can I do it? Any advice?

Thanks.

-- Important Edit --

Hey guys, sorry for changing my question but my requirements has been changed. I need to get the entire graph (all nodes and relationships) connected and disconnected except specific nodes by ids. The following query is working but only for single id, in case of more ids it isn't working.

MATCH (n) WHERE (n:person)
OPTIONAL MATCH (n)-[r:friend|connected|owner]-(m) WHERE (m:person OR m:dog OR m:cat)
WITH n,r,m
MATCH (excludeNode) WHERE excludeNode.id IN ['af97ab48544b']
WITH n,r,m,excludeNode WHERE NOT n.id = excludeNode.id AND (NOT m.id = excludeNode.id OR m is null)
RETURN n,m,r

Alternatively I tried simpler query:

MATCH (n) WHERE (n:person) AND NOT n.id IN ['af97ab48544b'] return n

But this one does not returns the relationships (remember I need disconnected nodes also).

How can I get the entire graph exclude specific nodes? That includes nodes and relationships, connected nodes and disconnected as well.

2
To clarify, you're looking for all nodes connected to your :person that aren't :persons/:dogs/:cats connected by :friend/:connected/:owner relationships? Or are you trying to find all :persons where these relationships to those nodes aren't present? Or are you trying to find all nodes across your entire graph that do not include any of the :person nodes (and connected nodes) from your query? What's an example of desired output?InverseFalcon
From your SQL statement and your problem description I infer you'd like to find all the person, dog, cat that are NOT connected to the person with the particular id?Christoph Möbius
Please read my last edit. Unfortunately my requirements has been changed.Shai M.

2 Answers

2
votes

try this:

match (n) where not n.id = 'id to remove' optional match (n)-[r]-(m) where not n.id in ['id to remove'] and not m.id in ['id to remove'] return n,r,m

1
votes

You've gotta switch the 'perspective' of your query... start by looping over every node, then prune the ones that connect to your person.

MATCH (bad:person) WHERE bad.id IN ['af97ab48544b']
WITH COLLECT(bad) AS bads
MATCH path = (n:person) - [r:friend|:connected|:owner] -> (m)
WHERE n._id = '' AND (m:person OR m:cat OR m:dog) AND NOT ANY(bad IN bads WHERE bad IN NODES(path))
RETURN path

That said, this is a problem much more suited to SQL than to a graph. Any time you have to loop over every node with a label, you're in relational territory, the graph will be less efficient.