Is is possible to use the value of a node property as a variable name for a relationship property?

I am trying to use the value of a node property as a variable name for a relationship property, and I haven't found any way to do it so far. Here is an example:

Let's say I have some node labels including:

(p:Person {id: #, name: "some name"})

(c:Currency {id: #, name: "currency symbol"})

(t:Transaction {id: #, amount: #}

In this case, the transaction is not linked to the currency, but ignore this for now. I want to create a relationship to show that some person transacted with another.

Assumptions:

1. c.name can be one of many currencies [USD, EUR, GBP, ... etc]

2. If person A sends multiple currencies to person B, then each currency will have its own transaction.

Now if p1 sent some amounts of USD and EUR to p2, I want to create a relationship as follows:

(p1:Person)-[TRANSACTED_WITH {USD: some amount, EUR: some amount}]->(p2:Person)

So I want the relationship to have the symbol name of a sent currency as the property name and the amount as the value of that property. There can be one or multiple currencies sent from A to B. So each relationship between two persons can have a different set of properties.

I tried the following, but it didn't work:

MERGE (p1:Person)-[TRANSACTED_WITH {c1["name"]: t1.amount}]->(p2:Person)

Is there actually any way to do that?

Property names must be literal values. You can try using apoc doIt procedure, as it will let you execution a cypher statement passed as a string. As such, you can create your cypher string with the relationship's property name substituted with the value you need.

https://neo4j.com/labs/apoc/4.2/overview/apoc.cypher/apoc.cypher.doIt/

Hi @TK36 !

As @glilienfield said, there're several APOC procedures that may help you with this. An example of this can be:

MATCH(p1:Person { id : $id1}), (t1:Transaction { id : $id2}), (c1:Currency {id : $id3}), (p2:Person { id : $id4})
with *
CALL apoc.create.relationship(p1, 'TRANSACTION',
apoc.map.fromValues([
    c1.name, t1.amount
]), p2) 
YIELD rel
RETURN rel;

Hey bennu,

I have a similar yet different problem, so maybe you could help me with that.
My query should in theory work like this:

MATCH  (n)-[x:EVALUATED_IN]->(m)<-[y:EVALUATED_IN]-(o) where x.Metric = y.Metric and x.Score > y.Score and n.ID <> o.ID
with *, (toFloat(x.Score) - toFloat(y.score)) as score
call apoc.create.relationship(n, "OVERPERFORMS", 
    apoc.map.fromValues([
        x.Metric, score, 
        "Experiment", m.ID])
    , o)
yield rel
return rel
;

But my created relationships only have the "Experiment": m.ID properties.
Do you have any idea why? (x.Metric is a valid property that every "EVALUATED_IN"-Property has)

Appreciate any ideas

I think your 'score' value is null, thus it is not added to the map. The cause is a misspelling in your formula. Note, that you have 'y.score', not 'y.Score' in the formula for 'score'.

Thanks, now it works. Typical mistake after trying out many different solutions and being tired. Should have had a look again a few hours later.