apoc icon indicating copy to clipboard operation
apoc copied to clipboard

apoc.refactor.mergeNodes choose the result properties randomly

Open neo-technology-build-agent opened this issue 3 years ago • 3 comments

Issue by PeterKazmirsky Tuesday Feb 19, 2019 at 15:58 GMT Originally opened as https://github.com/neo4j-contrib/neo4j-apoc-procedures/issues/1107


Guidelines Imagine that I have user cluster consisting of user ids from different data sources and all users are connected to one Root node. In case that user cluster contains more than one Root node I want to merge this Root nodes to one. For finding the Root nodes in cluster I am using apoc.path.subgraphNodes and the resulting Root nodes I am sending to apoc.refactor.mergeNodes to merge them to one Root node. I also set properties to procedure: mergeRels:true, properties:'overwrite'

Actual Behavior I cannot influence in what order roots get into procedure apoc.refactor.mergeNodes, so after merging the result Root node and his relationships properties will have random properties.

Expected Behavior I would like you to consider to add feature to apoc.refactor.mergeNodes where I can tell for example that for merging property "count" choose highest one. Or for "date" property choose latest one. Thank you.

Versions Neo4j 3.5.2 Apoc library 3.5.0.1

Comment by jexp Tuesday Feb 19, 2019 at 18:16 GMT


MergeNodes uses collection order You can use apoc.coll.sort to sort by a key you like

Comment by PeterKazmirsky Wednesday Feb 20, 2019 at 07:46 GMT


Thanks. But what about relationships. I recently created ticket where I asked to overwrite properties in relationships in procedure mergeNodes. And now I would like to sort properties of relationships and choose the proper one before merging. Is there any solution for that as well ?

Comment by vga91 Thursday Jun 24, 2021 at 15:06 GMT


With a simple dataset like:

create (r:Root), (r2:Root) with r, r2
create (r2)<-[:MyRel {prop: "prop1"}]-(n1:User{value:'node1'})-[:MyRel {prop: "prop11"}]->(r)
create (r2)<-[:MyRel {prop: "prop2"}]-(n2:User{value:'node2'})-[:MyRel {prop: "prop22"}]->(r)
create (r2)<-[:MyRel {prop: "prop3"}]-(n3:User{value:'node3'})-[:MyRel {prop: "prop33"}]->(r)

This could be solved in this way:

Match (r:Root) 
with collect(r) as nodes    // I CAN ORDER NODES HERE
CALL apoc.refactor.mergeNodes(nodes, {properties:'overwrite'}) YIELD node // NO mergeRels:true
WITH node 
match (node)-[r]-(user:User)
with user, collect(r) as rels   // I CAN ORDER RELS HERE
call apoc.refactor.mergeRelationships(rels, {properties: 'DISCARD'}) yield rel return rel
// with {properties: 'DISCARD'} we choose the first in order of appearance, otherwise the last

Closing as a workaround was produced and there has been no further comment in over 2 years

gem-neo4j avatar Jan 02 '25 13:01 gem-neo4j