Creating a patient trajectory, looping through patients, encounters and timestamps

I'm working on creating patient trajectories using neo4j. I have been successful with a single patient trajectory and can use the timestamp to create a "NEXT_EVENT" relationship. This works well for a single patient and single encounter (hospital visit), but I'm having some issues when I try to loop through patients, then encounter and create the timestamps relationships. My goal is to identify the encounters and create the relationships via the timestamp, similar to creating a timeseries/timeline for each patient encounter.

This is the example on the single patient:
// Create patient node
CREATE (p:Patient {patientID: "P001", name: "John Doe", birthdate: "1980-01-01"})

// Create encounter node
CREATE (e:Encounter {encounterID: "E001", patientID: "P001", timestamp: "2023-03-01T00:00:00", startTime: "2023-03-01T00:00:00", endTime: "2023-03-10T00:00:00"})

// Create relationships between patient, encounter, and other nodes
MATCH (p:Patient {patientID: "P001"})
MATCH (e:Encounter {encounterID: "E001"})
CREATE (p)-[:HAS_ENCOUNTER]->(e)

// Create nodes for a single patient and their components
CREATE (a:Admission {patientID: "P001", timestamp: "2023-03-01T01:00:00"})
CREATE (d:Discharge {patientID: "P001", timestamp: "2023-03-10T00:00:00"})
CREATE (dx:Diagnosis {patientID: "P001", diagnosis: "Diabetes", timestamp: "2023-03-01T02:00:00"})
CREATE (vs1:VitalSign {vitalSignID: "VS001", testName: "Blood Pressure", timestamp: "2023-03-01T10:00:00", systolic: 120, diastolic: 80})
CREATE (vs2:VitalSign {vitalSignID: "VS002", testName: "Heart Rate", timestamp: "2023-03-01T10:00:00", value: 75})
CREATE (pr1:Procedure {procedureID: "PR001", procedureName: "ECG", timestamp: "2023-03-01T15:00:00"})
CREATE (mo1:MedicationOrder {orderID: "M001", medicationName: "Lisinopril", dosage: "10mg", timestamp: "2023-03-02T08:00:00"})
CREATE (lo1:LabOrder {orderID: "L001", testName: "CBC", timestamp: "2023-03-02T09:00:00"})
CREATE (hgb:Component {componentID: "C001", testName: "Hemoglobin", timestamp: "2023-03-02T12:00:00", value: 12.5})
CREATE (hct:Component {componentID: "C002", testName: "Hematocrit", timestamp: "2023-03-02T12:00:00", value: 36.0})
CREATE (mo2:MedicationOrder {orderID: "M002", medicationName: "Metformin", dosage: "500mg", timestamp: "2023-03-03T10:00:00"})
CREATE (pr2:Procedure {procedureID: "PR002", procedureName: "IV insertion", timestamp: "2023-03-03T10:00:00"})
CREATE (lo2:LabOrder {orderID: "L002", testName: "BMP", timestamp: "2023-03-04T14:00:00"})
CREATE (na:Component {componentID: "C003", testName: "Sodium", timestamp: "2023-03-04T17:00:00", value: 140})
CREATE (k:Component {componentID: "C004", testName: "Potassium", timestamp: "2023-03-04T17:00:00", value: 4.0})
CREATE (cl:Component {componentID: "C005", testName: "Chloride", timestamp: "2023-03-04T17:00:00", value: 100})

MATCH (e:Encounter {encounterID: "E001"})
MATCH (a:Admission)
CREATE (e)-[:HAS_ADMISSION]->(a)

// Create NEXT_EVENT relationships based on timestamps
MATCH (n)
WHERE n:Encounter OR n:Admission OR n:Diagnosis OR n:MedicationOrder OR n:LabOrder OR n:Procedure OR n:VitalSign OR n:Component OR n:Discharge
WITH n.timestamp AS ts, collect(n) AS nodes_at_timestamp
ORDER BY ts
WITH collect({ts: ts, nodes: nodes_at_timestamp}) AS timestamp_groups
UNWIND range(0, size(timestamp_groups) - 2) AS i
WITH timestamp_groups[i] AS group1, timestamp_groups[i + 1] AS group2
UNWIND group1.nodes AS n1
UNWIND group2.nodes AS n2
CREATE (n1)-[:NEXT_EVENT]->(n2)

/////

When I have more than one patient and multiple encounters, I struggle with the loop.
Examples:

// Create patient nodes
CREATE (p1:Patient {patientID: "P001", name: "John Doe", birthdate: "1980-01-01"})
CREATE (p2:Patient {patientID: "P002", name: "Jane Doe", birthdate: "1985-01-01"})

// Create encounter nodes for each patient
CREATE (e1:Encounter {encounterID: "E001", patientID: "P001", timestamp: "2023-03-01T00:00:00", startTime: "2023-03-01T00:00:00", endTime: "2023-03-10T00:00:00"})
CREATE (e2:Encounter {encounterID: "E002", patientID: "P001", timestamp: "2023-04-01T08:00:00", startTime: "2023-04-01T00:00:00", endTime: "2023-04-10T00:00:00"})
CREATE (e3:Encounter {encounterID: "E003", patientID: "P002", timestamp: "2023-02-01T00:00:00", startTime: "2023-02-01T00:00:00", endTime: "2023-02-10T00:00:00"})
CREATE (e4:Encounter {encounterID: "E004", patientID: "P002", timestamp: "2023-03-01T08:00:00", startTime: "2023-03-01T00:00:00", endTime: "2023-03-10T00:00:00"})

//Encounter 1 - Patient 1
// Create nodes for Encounter 1
CREATE (a1:Admission {patientID: "P001", encounterID: "E001", timestamp: "2023-03-01T01:00:00", location: "ICU"})
CREATE (d1:Discharge {patientID: "P001", encounterID: "E001", timestamp: "2023-03-06T00:00:00", disposition: "Home"})
CREATE (dx1:Diagnosis {patientID: "P001", encounterID: "E001", diagnosis: "Diabetes", timestamp: "2023-03-01T02:00:00"})
CREATE (vs1:VitalSign {patientID: "P001", encounterID: "E001", vitalSignID: "VS001", testName: "Blood Pressure", timestamp: "2023-03-01T10:00:00", systolic: 120, diastolic: 80})
CREATE (vs2:VitalSign {patientID: "P001", encounterID: "E001", vitalSignID: "VS002", testName: "Heart Rate", timestamp: "2023-03-01T10:00:00", value: 75})
...

I tried using this code snippet, but only creates the "NEXT_EVENT" relationship on the first encounter.
// Create NEXT_EVENT relationships based on timestamps
MATCH (e:Encounter)
WITH collect(e) AS encounters
UNWIND encounters AS encounter
MATCH (n)
WHERE (n:Encounter OR n:Admission OR n:Diagnosis OR n:MedicationOrder OR n:LabOrder OR n:Procedure OR n:VitalSign OR n:Component OR n:Discharge)
AND n.encounterID = encounter.encounterID
WITH n.encounterID AS eid, n.timestamp AS ts, collect(n) AS nodes_at_timestamp
ORDER BY eid, ts
WITH eid, collect({ts: ts, nodes: nodes_at_timestamp}) AS timestamp_groups
UNWIND range(0, size(timestamp_groups) - 2) AS i
WITH timestamp_groups[i] AS group1, timestamp_groups[i + 1] AS group2
UNWIND group1.nodes AS n1
UNWIND group2.nodes AS n2
CREATE (n1)-[:NEXT_EVENT]->(n2)

Would appreciate any insight on any error you might see.

G

Try this:
I created the graph with your Cypher queries. I added encounterID and patientID properties every node other than Patient and Encounter nodes.

I created two patients "P001" and "P002" and used other Admission, Discharge .. nodes from your Patient P001 by simply changing the patientID to "P002" and encounterID to "E002".

Your query for creating relationship is fine and works for any number of patients. Minor change I used MERGE instead of CREATE:
// Create NEXT_EVENT relationships based on timestamps
MATCH (n)
WHERE n:Encounter OR n:Admission OR n:Diagnosis OR n:MedicationOrder OR n:LabOrder OR n:Procedure OR n:VitalSign OR n:Component OR n:Discharge
WITH n.timestamp AS ts, collect(n) AS nodes_at_timestamp
ORDER BY ts
WITH collect({ts: ts, nodes: nodes_at_timestamp}) AS timestamp_groups
UNWIND range(0, size(timestamp_groups) - 2) AS i
WITH timestamp_groups[i] AS group1, timestamp_groups[i + 1] AS group2
UNWIND group1.nodes AS n1
UNWIND group2.nodes AS n2
MERGE (n1)-[:NEXT_EVENT]->(n2)

Result: