cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Can we merge multiple Nodes based on Single common property

Hi All,

I am relatively new to neo4j and I am working on 1 Use case where we are trying to merge all nodes(with 1 common property, such as all nodes with year= "1995") into 1 node where all the relationships are heading towards it rather than 3 different nodes.

For example:-
I have 3 csv files with below type of data.

Actor.csv:-

Actor Id Name
1 Sam

Movie.csv:-

Movie Id Movie Name Year Actor Id Director Id
45 Avengers 2016 1 10
23 Movie 2 2016 1 10
12 Movie 3 2016 1 10

Director.csv:-

Director ID Director Name
10 Danny Morgan

Now if I use the following Cypher Query:-

Match (actor:Actor)-[:ACTED_IN]->(movie:Movie)<-[:DIRECTED_BY]-(director:Director)
return actor, movie, director

Now the graph that appears have 1 node of actor and 3 nodes of movie then 1 node of director.
all connected via relationships.

I want there to be only 1 node of movie displaying "2016" as year and 3 edges/relationships going out of actor to the movie node and 3 edges/relationships merging as 1 into Director node
or
1 single relationship of "ACTED_IN" going towards movie but a number "3" (suggesting there are 3 relationships for that year) written over it

The main goal is to show that there are 3 realtionships related to the year 2016.
I know we can perform aggregations to return tables with count or arrays of data.
But can we do it in graph nodes as well.

NOTE:-I am using Neo4j Browser version 3.1.4

Thank you for reading I hope it's not a silly question.

1 ACCEPTED SOLUTION

It doesn't work like that (pairwise merges) as it would do random pairs and then randomly try to merge them where half of them are already gone.

MATCH (f:ABC)
WITH f.counterparty as counterparty, f.clientName as clientName, collect(f) as nodes
WHERE size(nodes) > 1
call apoc.refactor.mergeNodes(nodes) yield node 
return count(*)

View solution in original post

12 REPLIES 12

HI Mike.
Thanks for the reply.
I followed exact same steps mentioned.

I created 2 nodes:
Here "Foo" have 202 as id and "Bar" have 203 as id.

CREATE (f:Sample {name:'Foo'}), (b:Sample {surname:'Bar'}) RETURN f,b

Then i run the following CYPHER command:-

MATCH (f:Sample {name:'Foo'}), (b:Sample {surname:'Bar'})
CALL apoc.refactor.mergeNodes([f,b])
YIELD node RETURN node

I get the following error but i do not understand why am i getting it and what to make of it.

Neo.ClientError.Statement.EntityNotFound: Node with id 203 has been deleted in this transaction

Hey,
please try once below query

MATCH (f:Sample {name:'Foo'}),(b:Sample {surname:'Bar'})
WITH * LIMIT 1
call apoc.refactor.mergeNodes([f,b]) yield node
return "none"

It did nothing. Just showed this:

none
"none"

Nothing else.

Now search for the node .
It must present in your database.
If it executed well that means merging is complete

wow. It worked.
Thanks.

Can you plz tell why it did not work in previous case. And what did we do differently or the analogy of your solution.

Hi Again,
It worked fine when we have to merge 2 nodes of same Label but with different Properties.
Like properties Name and Surname under common label **Sample** in above comments.

But in my case where properties are common.

For Example:-
Label ABC have 40 nodes with following properties.

{
sid:1 to 40 //Unique for all 40 nodes
counterparty: "Harley Davidson" //same for all 40 nodes.
clientName:"Indian Motors" //Also same for all 40 nodes
}

I used this:-

MATCH (f:ABC{counterparty:'Harley Davidson'}),(b:ABC{counterparty:'Harley Davidson'})
WITH * LIMIT 1
call apoc.refactor.mergeNodes([f,b]) yield node
return "none"

I tried to merge 40 nodes with 1 property as common among all. It executed fine displaying none as output just like previously. But still I see there are 40 nodes under ABC instead of 1.

Which version do you use?

I am using
Neo4j Browser version 3.2.10
Neo4j Server Version 3.4.9(community)
APOC :- apoc-3.4.0.3-all.jar

It doesn't work like that (pairwise merges) as it would do random pairs and then randomly try to merge them where half of them are already gone.

MATCH (f:ABC)
WITH f.counterparty as counterparty, f.clientName as clientName, collect(f) as nodes
WHERE size(nodes) > 1
call apoc.refactor.mergeNodes(nodes) yield node 
return count(*)

Great Sir. It worked.
Tons of thanks.
I need to deep dive rather than just learning match, create and where clauses of Neo4j.
Only if my manager give me time to learn..lol

Again,
Thanks everybody for their input