0
votes

In Neo4j, how can I merge all nodes by a single property i.e. node1.property1=node2.property2? Or, how can I merge all nodes that have the same label name?

In the manual, it talks about this for individual nodes:

MATCH (person:Person)
MERGE (city:City { name: person.bornIn })
RETURN person.name, person.bornIn, city

Three nodes labeled City are created, each of which contains a name property with the value of New York, Ohio, and New Jersey, respectively. Note that even though the MATCH clause results in three bound nodes having the value New York for the bornIn property, only a single New York node (i.e. a City node with a name of New York) is created. As the New York node is not matched for the first bound node, it is created. However, the newly-created New York node is matched and bound for the second and third bound nodes.

Result

5 rows Nodes created: 3 Properties set: 3 Labels added: 3

My problem is that my node labels are variable and so I would have to do the above code for every node that contains a different label (the label in the above example is Person). For my example, if nodes have the property value , they will also have the same label.


UPDATE: So, now I'm not sure my original question is what I need after all (I will clean up the question once things come into focus better).

My problem is that I have two node-edge-node instances

(node1) -[relation1]-> (node2)

and

(node2) -[relation2]->(node3)

where node1, node2, etc. are the labels for each node-edge-node. Note, node2 may have some different property values across different instances and there may be many nodes with label node2, each having exactly one relationship as shown above. Some properties will always be the same (unique identifiers related to the label name) though.

With that said, I'd like to run the query:

MATCH (n1: node1) -[r1: relation1]->
(n2: node2) -[r2: relation2]-> (n3: node3)
RETURN n1, r1, n2, r2, n3

but since there are many nodes with label node2 but none of them are connected (or merged?), the above query returns nothing. So, how can I merge all nodes with the same label so the query works as I would like?

1
when you say merge all nodes, are they nodes with same or different parameters? Could you give a real example?Rob
Merge is a combination of Match and Create, it's used to not create duplicate nodes. I'm not sure what you're talking about specificallyRob
@spwallace: You did not finish your edited question.cybersam
Sorry, I was a bit confused about what exactly I wanted but I updated the question now so it is (hopefully) more clear about my exact problem.Sergei Wallace
Can you provide details about exactly how you would decide whether 2 node2 nodes should be merged?cybersam

1 Answers

0
votes

You can tweak the query from the manual so that it works for any node that has a label from a specified collection (e.g., ['Person', 'Foo', 'Bar']). (The query below assumes that all such nodes have name and bornIn properties.)

MATCH (person)
WHERE ANY(x IN LABELS(person) WHERE x IN ['Person', 'Foo', 'Bar'])
MERGE (city:City { name: person.bornIn })
RETURN person.name, person.bornIn, city;

The above query can be tweaked to pass the list of labels in a parameter, which is more efficient if there are multiple sets of labels.

Another way of doing the same thing, if the set of labels does not change:

MATCH (person)
WHERE person:Person OR person:Foo OR person:Bar
MERGE (city:City { name: person.bornIn })
RETURN person.name, person.bornIn, city