Drug interaction network for patient safety

Flag dangerous drug combinations across all patients via a prescribed-drug interaction graph

All recipes· graph· 7 minutesintermediatecypher

Drug interaction network for patient safety

Objective

Pharmacists and clinical decision-support systems must flag patients on combinations of drugs known to interact dangerously. Modeling Patient → Drug and Drug → Drug interactions as a graph turns the screening query into one MATCH that looks for triangles in the network — sub-second even across a hospital's entire prescription history.

Step 1: Create the graph

// Patients
MERGE (p1:Patient {mrn: "MRN-101", name: "Sarah Chen",   age: 67})
MERGE (p2:Patient {mrn: "MRN-102", name: "Raj Patel",    age: 54})
MERGE (p3:Patient {mrn: "MRN-103", name: "Mia Rossi",    age: 71})
MERGE (p4:Patient {mrn: "MRN-104", name: "Leo Park",     age: 49})
MERGE (p5:Patient {mrn: "MRN-105", name: "Eli Tanaka",   age: 62})

// Drugs
MERGE (warf:Drug {name: "Warfarin",   class: "Anticoagulant"})
MERGE (asp:Drug  {name: "Aspirin",    class: "NSAID"})
MERGE (clop:Drug {name: "Clopidogrel", class: "Antiplatelet"})
MERGE (sim:Drug  {name: "Simvastatin", class: "Statin"})
MERGE (ery:Drug  {name: "Erythromycin", class: "Antibiotic"})
MERGE (met:Drug  {name: "Metformin",  class: "Antidiabetic"})
MERGE (lis:Drug  {name: "Lisinopril", class: "ACE Inhibitor"})

// Prescriptions
MERGE (p1)-[:PRESCRIBED {since: "2026-01-12"}]->(warf)
MERGE (p1)-[:PRESCRIBED {since: "2026-03-04"}]->(asp)
MERGE (p2)-[:PRESCRIBED {since: "2025-11-22"}]->(sim)
MERGE (p2)-[:PRESCRIBED {since: "2026-04-15"}]->(ery)
MERGE (p3)-[:PRESCRIBED {since: "2026-02-08"}]->(warf)
MERGE (p3)-[:PRESCRIBED {since: "2026-02-08"}]->(clop)
MERGE (p4)-[:PRESCRIBED {since: "2025-06-10"}]->(met)
MERGE (p4)-[:PRESCRIBED {since: "2025-06-10"}]->(lis)
MERGE (p5)-[:PRESCRIBED {since: "2026-03-30"}]->(asp)
MERGE (p5)-[:PRESCRIBED {since: "2026-03-30"}]->(clop)

// Known interactions (severity 1=mild, 2=moderate, 3=severe)
MERGE (warf)-[:INTERACTS_WITH {severity: 3, effect: "Major bleeding risk"}]->(asp)
MERGE (warf)-[:INTERACTS_WITH {severity: 3, effect: "Major bleeding risk"}]->(clop)
MERGE (asp)-[:INTERACTS_WITH  {severity: 2, effect: "Increased bleeding"}]->(clop)
MERGE (sim)-[:INTERACTS_WITH  {severity: 3, effect: "Rhabdomyolysis risk"}]->(ery);

Step 2: Find at-risk patients across the entire panel

// Triangle: Patient -> drugA, Patient -> drugB, drugA <-> drugB interacts.
MATCH (p:Patient)-[:PRESCRIBED]->(a:Drug)-[ix:INTERACTS_WITH]-(b:Drug)<-[:PRESCRIBED]-(p)
WHERE id(a) < id(b)              // de-duplicate the unordered drug pair
RETURN p.mrn  AS mrn,
       p.name AS patient,
       a.name AS drug_a,
       b.name AS drug_b,
       ix.severity AS severity,
       ix.effect   AS effect
ORDER BY severity DESC, patient;

What's happening

  • The pattern matches a triangle: same patient, two drugs they take, one interaction edge between the drugs. Cypher unifies the patient on both sides of the pattern automatically.
  • id(a) < id(b) is a standard idiom to avoid returning each interaction twice.
  • The interaction edge is undirected (-[ix:INTERACTS_WITH]-) because pharmacological interactions are symmetric — a single relationship covers both directions.
  • In SQL this is a 4-way join (patient_drug × drug_interactions × patient_drug × drugs) plus a filter to ignore the same drug — the graph version is shorter and runs in linear time per prescribed drug, not quadratic in the prescription table.
  • Severity 3 alerts feed directly into prescribing UIs as "do not dispense without override".

Try this next

MATCH (p:Patient)-[:PRESCRIBED]->(d:Drug)
RETURN p.name AS patient, collect(d.name) AS regimen, count(d) AS poly_count
ORDER BY poly_count DESC;
MATCH (d1:Drug)-[ix:INTERACTS_WITH]-(d2:Drug)
WHERE id(d1) < id(d2)
RETURN d1.name, d2.name, ix.severity, ix.effect
ORDER BY ix.severity DESC;
MATCH (p:Patient)-[:PRESCRIBED]->(:Drug)-[:INTERACTS_WITH]-(:Drug)<-[:PRESCRIBED]-(p)
RETURN p.mrn, p.name, count(*)/2 AS conflicting_pairs;

Tags

graphcypherhealthcareintermediate

Run this on your own machine

Install SynapCores Community Edition free, paste the SQL or Cypher above into the bundled web UI, and watch it run.

Download Free CE