I have an array of multiple IDs of nodes to delete. Every Cypher example I can find either deletes one node or all nodes. How would one delete nodes that match an array of IDs, in a single query?
Something like this... (pseudocode):
MATCH (n:Node) WHERE (n.id in ['id_a', 'id_b']) DELETE n;
You can use the IN list operator:
If id is a property:
WITH [1,2,3,4] AS ids
MATCH (n) WHERE n.id IN ids
DETACH DELETE n;
If by id you mean the internal node id:
WITH [1,2,3,4] AS ids
MATCH (n) WHERE id(n) IN ids
DETACH DELETE n;
Related
I have a collection of element ids. I am currently using an UNWIND to find nodes that match at least one element.
UNWIND ids as id
MATCH (e:Element)-[]-(f:Foo {id:id})
RETURN DISTINCT e
I wanted to find out how I could find the elements that match ALL the ids. Such that if I have 5 ids, the elements that have a relation to all 5 matching nodes and exclude nodes that only match 1 or 2.
I was thinking I could do something with COUNT and pass in the number of elements as a query parameter, but that seemed pretty hacky.
Does anyone know how to do return nodes that match all elements in a collection?
Is there only a single relationship between Element and Foo nodes? If so, how about comparing the number of ids you have to the number of relationships connecting each distinct Element to Foo nodes:
UNWIND ids AS id
MATCH (e:Element)-[r]->(f:Foo {id: id})
WITH e, COUNT(r) AS num WHERE num = SIZE(ids)
RETURN e
I want to connect a first node of a list with other nodes of the list via relationship in Neo4j.
My approach is :
MATCH (n)
WITH n.title AS id, COLLECT(n) as nodes
where size(nodes)>1 ,COALESCE(COLLECT(n)) as firstNode
UNWIND TAIL(nodes) as x
CREATE (firstNode)-[r:Child]->(x)
return r
Basically I have some nodes with same titles. I want them to club together and make one of the element of that same title group as superior by creating a child relationship with other nodes in the list.
Try it:
MATCH (n)
WITH n.title AS id, collect(n) as nodes
WHERE size(nodes) > 1
WITH nodes[0] as firstNode, nodes[1..] as otherNodes
UNWIND otherNodes as other
CREATE (firstNode)-[r:Child]->(other)
In the second WITH I'm extracting the first node and a list from the second node to the end of the list. Then I unwind the otherNodes list and create the desired relationship between the firstNode and the unwinded nodes.
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.
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
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.
In SQL:
Delete From Person Where ID = 1;
In Cypher, what's the script to delete a node by ID?
(Edited: ID = Neo4j's internal Node ID)
Assuming you're referring to Neo4j's internal node id:
MATCH (p:Person) where ID(p)=1
OPTIONAL MATCH (p)-[r]-() //drops p's relations
DELETE r,p
If you're referring to your own property 'id' on the node:
MATCH (p:Person {id:1})
OPTIONAL MATCH (p)-[r]-() //drops p's relations
DELETE r,p
The cleanest sweep for a node with id "x" is
MATCH (n) where id(n) = x
DETACH DELETE n
https://neo4j.com/docs/cypher-manual/current/clauses/delete/#delete-delete-a-node-with-all-its-relationships
https://neo4j.com/docs/cypher-manual/current/functions/scalar/#functions-id
Old question and answered, but to delete node when it has relationships, use DETACH
MATCH (n) where ID(n)=<your_id>
DETACH DELETE n
or otherwise you get this:
Neo.ClientError.Schema.ConstraintValidationFailed: Cannot delete node<21>, because it still has relationships. To delete this node, you must first delete its relationships.
It's like SQL's CASCADE
When the node is a orphan.
Start n=node(1)
Delete n;
Following the link provided by #saad-khan, here's an example for getting the nodes and relationships ids.
The code below shows the ids, so you can make sure that you're deleting everything related to the given ID.
MATCH (node)-[relation:HAS]->(value)
where ID(node)=1234
RETURN ID(instance), ID(value), ID(r)
Ps.: ":HAS" is an example of an relationship.
I have a scenario where I know IDs of a list of nodes.
I need to get connection(if exists) between these nodes given their IDs.
Is there any way to achieve this?
Update:
I am using node id property not the neo4j's internal ID(using like match (n:Person{id:3}))
You can use the IN clause to select from a list of values:
MATCH (n)-[r*..2]-(m)
WHERE ID(n) IN [0,1,2] AND ID(m) IN [2,3,4]
RETURN r
I've limited the path length to 2 hops of indeterminate relationship type here, and arbitrarily picked some IDs.
To return the path instead:
MATCH p=(n)-[r*..2]-(m)
WHERE ID(n) IN [0,1,2] AND ID(m) IN [2,3,4]
RETURN p
START n=node(1,2,3,4,5,6) //your IDs of a list of nodes
MATCH p=n-[r]-m //the connection for 1 hop. for multiple hops do n-[r*]-m
WHERE Id(m) in [1,2,3,4,5,6] //your IDs of a list of nodes
RETURN p