How to keep node relationship unique

I have a compound flow in neo4j and unable to understand how to keep this flow unique.

patient-1
visit date 29-03
-- visit time
--- treatment

Let us say I have inserted these nodes with some data in each . what I exactly want to update the same record and from the visit, date adds a new node of-course for time and treatment as well.
So i will have all visit dates and time with treatment details.
when I am trying to add the second patient in the same date,
patient-2
-visit date 29-03
-- visit time
--- treatment

cypher is not creating a separate date node for each patient, but it creates a relation with the existing node, which is for patient 1.
also, i can have multiple time treatment nodes on a single date. Please share the syntax of query. which can add this

patient node (unique )

  • date (single patient can have multiple visit so can be multiple)
    --- time (in single date there can be multiple time nodes)
    ---treatment (in single date there can be multiple treatments)

all patient should not have any relation with each other in any term

sample query

MERGE (nodepatient:ip { ip: "%s"})

MERGE(nodeDate:visitDate { date: "%s"})
MERGE(nodeTime:visitTime { time: "%s"})
MERGE(nodetreatment:treatment { treatment: "%s"})

WITH nodepatient ,nodeDate, nodeTime, nodetreatment

MERGE(nodepatient)-[:visitDate]->(nodeDate)-[:visitTime]->(nodeTime)-[:treatment]->(nodetreatment)

Welcome to the community! What you're asking about is a pretty common ask here on the forums but basically the answer is there's no way that you can you create a constraint on the Neo4j instance to make a relationship unique. You'll need to figure out a way to do that programmatically on your end. But some of the things you can so is check to see if a relationship already exists on the node something like:

MATCH (p:Patient)-[r:VISITED]->(v:visit)
WHERE NOT r 
....your logic here

is something you can do to make sure you're dealing with a node with no relationships.

1 Like

thanks @MuddyBootsCode for your response . but my design is some thing like every patient must should have own date time and multiple treatment its possible to create once but when i am trying to update existing it mess up the record

I understand. But you'll have to change your data structure a bit to accommodate what you're trying to do in Neo4j.

Try this:

//Patient: John..............

MERGE (nodepatient:ip { ip: "John"})

CREATE(nodeDate:visitDate { date: "01/01/2020"})
CREATE(nodeTime:visitTime { time: "8.40"})
CREATE(nodetreatment:treatment { treatment: "Cough"})

WITH nodepatient ,nodeDate, nodeTime, nodetreatment

MERGE(nodepatient)-[:visitDate]->(nodeDate)-[:visitTime]->(nodeTime)-[:treatment]->(nodetreatment)

//Patient Jane..........

MERGE (nodepatient:ip { ip: "Jane"})

CREATE(nodeDate:visitDate { date: "01/01/2020"})
CREATE(nodeTime:visitTime { time: "8.30"})
CREATE(nodetreatment:treatment { treatment: "Fever"})

WITH nodepatient ,nodeDate, nodeTime, nodetreatment

MERGE(nodepatient)-[:visitDate]->(nodeDate)-[:visitTime]->(nodeTime)-[:treatment]->(nodetreatment)
;

Result:

If John visits the hospital say next day:

MERGE (nodepatient:ip { ip: "John"})

CREATE(nodeDate:visitDate { date: "01/02/2020"})
CREATE(nodeTime:visitTime { time: "9.40"})
CREATE(nodetreatment:treatment { treatment: "Cough"})

WITH nodepatient ,nodeDate, nodeTime, nodetreatment

MERGE(nodepatient)-[:visitDate]->(nodeDate)-[:visitTime]->(nodeTime)-[:treatment]->(nodetreatment)

Result:

Use MERGE for patient and use CREATE for all other things the patient does at the hospital.

2 Likes

thanks for such a nice solution but the problem is when same customer comes second time in same date in that case i don't need to recreate date node and when i am using merge it is merging all nodes with same date . this is what i want to figure out

That can be handled this way: Say John visits second time on the same date.

Here is the solution:

match (a:ip)-[:visitDate]-(b:visitDate)
where a.ip = "John" and b.date = "01/01/2020"
create (b1:visitTime {time: "9.40"})
merge (b)-[:visitTime]->(b1)
create (c:treatment {treatment: "Fever"})
create(b1)-[:treatment]->(c)
return a, b, b1, c

Result:

Same way you can add any number of visits by the same patient same day at different times and for different/same treatments. This way, you will see many branches under the visitDate node for the same patient with each branch reflecting patient's visit times.

great idea and what about the performance like for millions of record may be you can say i am over engineering it but actually i want to make system scale able .
so two questions with reference.
1: what if date node dosen't exist it should create in that situation .
2: is this solution suitable for millions of record . ?
i have tested some thing like this .
query 1 : match parent node and option match date and time .
then on the basis of this result i am creating missing nodes . so lets say if date was not there and of-course in that case time also not there so creating both nodes .
so basically 2 queries for proper insertion . and these queries are taking 5 ms total . so a complete data along with relation is persisting in 5 ms time is to costly :(
once again Thanks in advance

The model is very flexible and can be expandable. For better performance, one must use constraints and indexes. With respects to patients, the root node is patient name node and down in the hierarchy it is visitDate-visitTime-treatment.

  1. For each patient, you need to create a visitDate node for each calendar date, vistiTime, treatment.

  2. Yes

For every patient you need to create one patient node. Each patient node will have multiple branches with each branch representing a visitDate. Further, each visitDate node will have multiple branches with each branch representing a visitTime.

Parent node: Patient name
Child node: visityDate
Grand Child node: visitTime
Great Grand Child node: treatment

For searching you have to match patient name, visitDate and visitTime.