Reputation: 2041
Suppose I have a parameter called nodes:
"nodes": [
{
"name": "John",
"age": 18.0,
"label": "Person",
"labeledName": "Unit1"
},
{
"name": "Phill",
"age": 23.0,
"label": "Animal",
"labeledName": "Unit2"
}
]
I want to unwind the parameter and create a node for each map with the property-value pairs listed. However, I need to reuse some of these nodes later on in the query, so I need to set a variable for each of them. Also, I want to dynamically set this variable (so that no two nodes have the same name). The variable name would be the value of the "labeledName" property.
In essence, for the nodes listed above, I'd need to do:
CREATE (Unit1:Person {name: 'John', age: '18'})
CREATE (Unit2:Animal {name: 'Phill', age: '23' })
There are two problems that I can't solve when using UNWIND for the same thing:
I can't set the properties "name" and "age" while omitting "label" (since it's used only as the node label) and "labeledName"
This means that something like this doesn't work:
UNWIND {nodes} as node WITH node, node.label AS label, node.labeledName AS variableName CREATE (variableName:label) SET variableName += node // somehow need to let it know NOT to set 'label' and 'labeledName' properties
This is where I got stuck. Using node.labeledName AS variableName doesn't work (but using node.label AS label does)
Any help is much appreciated!
Upvotes: 3
Views: 938
Reputation: 30407
So first off, you cannot assign variable names dynamically, that's impossible in Cypher.
But...using APOC Procedures you can create a map of a string name (your labeledName) to the node that you create, and then do lookups in the map dynamically to get at your nodes.
Also, you can't set a label dynamically with Cypher, but again we can use APOC Procedures to do this.
We can use APOC again to remove a property from the input maps for setting the properties.
Here's an example. Note that you can't use quoted string keys in your maps, so I've removed them:
UNWIND [
{
name: "John",
age: 18.0,
label: "Person",
labeledName: "Unit1"
},
{
name: "Phill",
age: 23.0,
label: "Animal",
labeledName: "Unit2"
}
] as input // though you would typically pass this as a map parameter
CREATE (n)
WITH input, n
CALL apoc.create.addLabels(n, [input.label]) YIELD node
SET n += apoc.map.removeKeys(input, ['label', 'labeledName'])
WITH collect([input.labeledName, n]) as pairs
WITH apoc.map.fromPairs(pairs) as mapping
...
With that mapping, you can lookup a value by key: mapping['Unit2']
will get you the corresponding node, and the string you pass can be dynamic from a string variable.
Upvotes: 1