xmlParser
xmlParser

Reputation: 2041

Is it possible do dynamically set a variable node name for each node created during UNWIND?

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:

  1. I can't set the variable name for each node
  2. 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

Answers (1)

InverseFalcon
InverseFalcon

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

Related Questions