Iterate over list of objects and create nodes by properties of objects

hi! I have a list of objects, the objects have different properties.

array = [{name: 'Armen', age: 26}, {name: 'Alex', profession: 'Scientist'}]

I need to iterate over list and create nodes with properties provided by objects. Which is the easiest and best practice way to do it? Thanks in advance! I have tried to use unwind both for list and object keys like this

with array as nodes 
unwind nodes as node
unwind keys(node) as prop 
with node, prop
merge (man: Man {prop:node[prop]}) 
return man

but in this case I get one node for each property.

Hello @armensanoyan :slight_smile:

You have create your nodes with this query:

WITH [{name: 'Armen', age: 26}, {name: 'Alex', profession: 'Scientist'}] AS nodes 
UNWIND nodes AS node
CREATE (man:Man)
SET man += node 
RETURN man

But if you want to use the MERGE clause, a good practice is to have a unique identifier for each node:

WITH [{id: 0, name: 'Armen', age: 26}, {id: 1, name: 'Alex', profession: 'Scientist'}] AS nodes 
UNWIND nodes AS node
MERGE (man:Man {id: node.id})
SET man += node 
RETURN man

Regards,
Cobra

1 Like

Thank you this is exactly what I need! Since I have id in my object I will use the second one to create and update by one query!

1 Like

Be aware that this query is not optimized if you want to load a lot of nodes, but this is the basis :slight_smile:

1 Like

Actually my plan is to load big data too, in some cases it can be millions of nodes so what is your advice for that scenario ? Thank you for warning!

Do you use CSV or data are coming from a script?

No it's inside nodejs script.

So, you will need to use batches to load your nodes and relationships. A batch is a list of items and you can use a batch that is 1000 or 10,000 in size depending on the power of your computer.

First, you will have to create a UNIQUE CONSTRAINT on each node Label if you have unique identifer by label. Otherwise, you can create a unique constraint on a global Label like Node if all your labels share the same index.

Then, you can load your nodes like I showed you:

WITH [{id: 0, name: 'Armen', age: 26}, {id: 1, name: 'Alex', profession: 'Scientist'}] AS nodes 
UNWIND nodes AS node
MERGE (man:Man {id: node.id})
SET man += node 
RETURN man

If you want to specify the label, then you will have to use APOC:

WITH [{labels: ["Man"], id: 0, properties: {name: 'Armen', age: 26}}, {{labels: ["Man"], id: 1,  properties: {name: 'Alex', profession: 'Scientist'}}] AS batch
UNWIND batch AS n
CALL apoc.merge.node(n.labels, n.id, n.properties, {})
YIELD node
RETURN node

Regards,
Cobra

1 Like

Hi! Could you please explain what are arguments of apoc.merge.node(). I know that first one is array of labels and I assume that second one should identify the node and its' value never should changed. The third one should be properties, which should be created or updated. From documentation I didn't get what onMatchProps is for? The problem is this works for creating nodes but for updating seems like I should add fourth argument with properties to update. Thank you!
Armen

Hello @armensanoyan :slight_smile:

I answered in your first subject.

Regards,
Cobra