Skip to content

Instantly share code, notes, and snippets.

@Orbifold
Created March 5, 2023 10:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Orbifold/7d71e15f96c1eeae9d6ff1782e7c8158 to your computer and use it in GitHub Desktop.
Save Orbifold/7d71e15f96c1eeae9d6ff1782e7c8158 to your computer and use it in GitHub Desktop.
Less than 100 lines to talk to your Neo4j graph
require('dotenv').config()
const { Configuration, OpenAIApi } = require("openai");
const neo4j = require('neo4j-driver')
const driver = neo4j.driver(process.env.NEO4JURI, neo4j.auth.basic(process.env.NEO4JUSER, process.env.NEO4JPASSWORD))
const session = driver.session({ database: "biodb" })
const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY
});
const openai = new OpenAIApi(configuration);
let isConfidential = false;
const search = "What gene causes Osteosarcoma";
let answer = "";
async function tellme() {
let training = `
#How many times did patient id_1 visit the ICU?
MATCH (p:Patient)-[:HAS_STAY]->(v:PatientUnitStay) WHERE p.patient_id =~ '(?i)id_1' RETURN COUNT(v)
#When did patient id_1 visit the ICU?
MATCH (p:Patient)-[:HAS_STAY]->(v:PatientUnitStay) WHERE p.patient_id =~ '(?i)id_1' RETURN v.hospitaldischargeyear
#Which drug treats COVID-19?; Which kind of compound treats COVID-19?
MATCH (c:Compound)-[:treats]->(d:Disease) WHERE d.name =~ '(?i)COVID-19' RETURN c.name
#Which pathogen causes COVID-19?; What is the disease agent for COVID-19?; Which organism causes COVID-19?
MATCH (o:Pathogen)-[:causes]->(d:Disease) WHERE d.name =~ '(?i)COVID-19' RETURN o.name
#Which gene causes Christianson syndrome?
MATCH (g:Gene)-[r1:associates]->(d:Disease) WHERE d.name =~ '(?i)Christianson syndrome' RETURN g.name
#Tell me something about the disease named "Christianson syndrome"
MATCH (d:Disease) WHERE d.name =~ '(?i)Christianson syndrome' RETURN d.description
#I have Dyspepsia, Hiccup and Edema. What can be the cause of this?
MATCH (s1:Symptom) <-[:presents]- (d:Disease) WHERE s1.name =~ '(?i)Dyspepsia' MATCH (s2:Symptom) <-[:presents]- (d:Disease) WHERE s2.name =~ '(?i)Hiccup' MATCH (s3:Symptom) <-[:presents]- (d:Disease) WHERE s3.name =~ '(?i)Edema' RETURN d.name
#what kinds of side effects do Doxepin have?
MATCH (d:Compound)-[:causes]->(s:\`Side Effect\`) WHERE d.name =~ '(?i)Doxepin' RETURN s.name
#what functions does the gene PCBD1 have?
MATCH (g:Gene)-[:participates]->(f:\`Molecular Function\`) WHERE g.name =~ '(?i)PCBD1' RETURN f.name
#which kinds of cancers can be found in frontal sinus?; Which tumors can you find in frontal sinus?
MATCH (d:Disease)-[:localizes]->(a:Anatomy) WHERE a.name =~ '(?i)frontal sinus' AND (d.name CONTAINS "cancer" OR d.disease_category = "Cancer") RETURN DISTINCT(d.name)
#`;
let query = training + search + "\n"
try {
const response = await openai.createCompletion("davinci", {
prompt: query,
temperature: 0,
max_tokens: 150,
top_p: 1.0,
frequency_penalty: 0.0,
presence_penalty: 0.0,
stop: ["#", ";"],
});
let cypher = response.data.choices[0].text;
try {
const result = await session.run(cypher)
const records = result.records
records.forEach(element => {
answer += element.get(0) + ", "
});
answer = answer.slice(0, -2)
// console.log("records", records)
} finally {
await session.close()
}
await driver.close()
}
catch (e) {
console.error(e.message)
}
if (answer.startsWith("CONFIDENTIAL")) {
isConfidential = true;
}
console.log(search, ": ", answer);
}
tellme();
@Orbifold
Copy link
Author

Orbifold commented Mar 5, 2023

Yes, you need a biomed database to fetch the data. See Hetionet for instance.
You also need a .env file with credentials, insert your OpenAI and Neo4j credentials like so:

NEO4JPASSWORD=xyz
NEO4JURI=bolt://localhost:7687
NEO4JUSER=neo4j
OPENAI_API_KEY=uvw

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment