Reputation: 1
I'm trying to learn more about Neo4j. Is there a way to group nodes that have the same name/number/etc.?
In standard RDBMS one can use the "Group by" clause to combine specific values into one. Have a look at the picture for a better understanding.
I'd like to combine these two nodes ("EE", "EE") into one, which has both sub-nodes.
Code for the image output:
match (A:Place)-[:`->`]-(B:Typ)
where A.name ='City1'
return A, B
Upvotes: 0
Views: 204
Reputation: 363
Just in case you were not aware: if you are looking to permanently merge nodes into 1 merging the relationships too, you can use APOC. If all the properties (except for the internal node id) are the same, then maybe.
CALL apoc.refactor.mergeNodes([node1, node2])
Upvotes: 1
Reputation: 5047
There is no equivalent for SQL's GROUP BY
clause in Cypher, as it is done implicitly. So whenever you use an aggregating function, such as count
, sum
, min
or collect
, the rest of the variables in the tuple are grouped implicitly.
MATCH (a:Place {name: 'City1'})-[:`->`]-(b:Typ)
RETURN a.name, count(b)
However, it seems to me that you actually want to perform a transformation that combines parent nodes together (we could say that the nodes are "merged" together, but I would like to avoid that word, as there is a MERGE
clause in Cypher with different semantics -- see @cybersam's answer for details).
name
property to that node.In practice, this could be implemented with a query like this:
MATCH (a:Place {name: 'City1'})-[:`->`]-(b:Typ)
WITH a.name AS name, collect(a) AS as, collect(b) AS bs
CREATE (new:Place {name: name})
WITH as, bs, new
UNWIND bs AS b
CREATE (new)-[:`->`]->(b)
WITH as
UNWIND as AS a
DETACH DELETE a
While the query is quite complex, fortunately, it is easy to test on a toy data set:
CREATE
(:Place {name: 'City1'})-[:`->`]->(:Typ {name: 'B1'}),
(:Place {name: 'City1'})-[:`->`]->(:Typ {name: 'B2'})
This results in:
And is combined to:
Upvotes: 1
Reputation: 67019
When you created your Place
nodes, you should have used a MERGE operation instead of CREATE. For example, no matter how many times you execute the following, it will not create a duplicate Place
node if one already existed with the same name
:
MERGE (a:Place {name: 'City1'})
...
Also, before you use the MERGE
operation, you should make it work optimally by first creating an index on :Place(name)
(or a uniqueness constraint on the same node label and property).
Upvotes: 2