Neo4j - Cypher | Timestamp when a relationship takes place

I have a Spring boot app where i have defined some Queries. In of them i would like the database to track a timestamp at the time a certain query is fired and store it in a property of a node. There is a function timestamp() but i cant find in the docs what kind of args this takes and how to use it properly.

Lets say i have this query:

MATCH (p:Patient) WHERE ID(p) = ({0})
MATCH (d:Drug) WHERE ID(d) IN ({1})
CREATE (p)-[:GETS]->(d)

Lets say the user inserts the parameters, i would like to have a timestamp at every (d) node.

Tried this:

MATCH (p:Patient) WHERE ID(p) = 1693
MATCH (d:Drug) WHERE ID(d) IN [1671, 1679]
CREATE (p)-[:GETS]->(d {givenDate: datetime()})

But I get the error:

Cant create node 'd' with labels or properties here. The variable is already declared.

Seems like i am doing something wrong but i would like that both 1671 + 1679 get a new property givenDate with a datetime()

Upvotes: 0

Views: 923

Answers (3)

cybersam
cybersam

Reputation: 67009

  1. The timestamp function is documented to return:

the difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC. It is the equivalent of datetime().epochMillis.

  1. Your CREATE clause is trying to create a new node with the variable name d, which is not allowed since d is already declared (by the prior MATCH clause) for a different node. I suspect, though, you do not want to create a new node, but add a timestamp to the existing d node instead.

    This should work (and gurantee that all the Drug nodes are created with the same datetime value):

    WITH datetime() AS dt
    MATCH (p:Patient) WHERE ID(p) = 1693
    MATCH (d:Drug) WHERE ID(d) IN [1671, 1679]
    SET d.givenDate = dt
    CREATE (p)-[:GETS]->(d)
    

    However, there is a big flaw in your overall approach. Since there is only a single Drug node with a given native ID, every time a different patient takes the same drug, the existing givenDate will be changed. It would make more sense to put the datetime in the GETS relationship:

    WITH datetime() AS dt
    MATCH (p:Patient) WHERE ID(p) = 1693
    MATCH (d:Drug) WHERE ID(d) IN [1671, 1679]
    CREATE (p)-[:GETS {givenDate: dt}]->(d)
    

Upvotes: 1

TheTeacher
TheTeacher

Reputation: 510

you can use the SET clause of cypher to add new or update existing properties of a node

MATCH (p:Patient) 
WHERE ID(p) = 1693 
MATCH (d:Drug) 
WHERE ID(d) IN [1671, 1679] 
SET d.givenDate = datetime()
CREATE (p)-[:GETS]->(d) 

Upvotes: 1

Graphileon
Graphileon

Reputation: 5385

try this (also assuming that it might be better to put the timestamp on the relationship)

MATCH (p:Patient) WHERE ID(p) = 1693 
MATCH (d:Drug) WHERE ID(d) IN [1671, 1679] 
CREATE (p)-[r:GETS]->(d)
SET r.givenDate= datetime()

if you think the timestamp should be on d

SET d.givenDate= datetime()

Upvotes: 1

Related Questions