Neo4j variable as property name

Viewed 26

I'm trying to use a variable as a property name in neo4j

MATCH(e: Event {id: "123"})
MATCH(u: User {id: "456"})
MERGE (u)-[a:ACTION]->(e)
ON MATCH 
SET e[a.t] = e[a.t] - 1

This gives the error:

Invalid input '[': expected an identifier character, whitespace, '{', 'x/X', node labels, a property map, a relationship pattern, '.', '(', '=' or "+=" (line 5, column 6 (offset: 96))
"SET e[a.t] = e[a.t] - 1"

While according to this forum: it should be possible. Neo4j forum

What am I doing wrong?

2 Answers

The example as you pointed out in the forum uses the node['property'] form in the WHERE clause. It does not work when updating the property like you did.
For example, below query works

match (n:Actor)  
where n['name'] = "Neo"  
set n.age = 50 
return n

Result:

n
(0:Actor {age:50, name:"Neo"})

Query took 14 ms and returned 1 rows. 
Updated the graph - set 1 property

BUT THIS WILL NOT WORK:

 set n['age'] = 50

Whenever we want to create a relationship dynamically, and set its properties dynamically, we should use apoc.merge.relationship function. In this function you can dynamically provide startNode, endNode, properties to set onMatch and onCreate for the relationship and some other params as well. For your use case, you can try something like this:

MATCH(e: Event {id: "123"})
MATCH(u: User {id: "456"})
OPTIONAL MATCH (u)-[rel:ACTION]->(e)
CALL apoc.merge.relationship(
  u, 
  "ACTION",
  {},
  {},
  e,
  apoc.map.setKey({}, toString(rel.t), rel.t - 1)
)
YIELD rel
RETURN rel;

Also, note that we have to fetch the relationship using OPTIONAL MATCH so that we can access its properties when calling the apoc function. Finally, you will also need to install APOC library for the above query to work.

Related