Rules are what used to avoid creating redundant nodes . E.g. Encounter has object field called subject
, since every object makes a node in the graph
So a node called Subject
will be created without the Rules . But we specified rename subject
with patient
since we know that this object
refers to a patient object so instead of Subject
, Patient
node will be created or merged with existing Node.
rules := map[string]map[string]interface{}{
"Encounter": {
"subject": "patient",
"serviceProvider": "organization",
},
"Patient": {
"generalPractitioner": "practitioner",
},
}
Sample Usages
func main() {
data := []byte(`
{
"id": "49c2df26-6fb9-43fb-82a2-3bd413a95934",
"meta": {
"profile": [
"http://standardhealthrecord.org/fhir/StructureDefinition/shr-demographics-PersonOfRecord"
]
},
"identifier": [
{
"type": {
"coding": [
{
"system": "http://hl7.org/fhir/identifier-type",
"code": "SB"
}
]
},
"system": "http://hl7.org/fhir/sid/us-ssn",
"value": "999608294"
}
],
"name": [
{
"use": "official",
"family": "Abernathy691",
"given": [
"Carlotta591"
]
}
],
"telecom": [
{
"system": "phone",
"value": "1-892-670-6907 x741",
"use": "home"
}
],
"gender": "female",
"birthDate": "2004-09-12",
"address": [
{
"line": [
"775 Jerde Pike"
],
"city": "Sunderland",
"state": "MA",
"postalCode": "01375",
"country": "US"
}
],
"maritalStatus": {
"coding": [
{
"system": "http://hl7.org/fhir/v3/MaritalStatus",
"code": "S"
}
],
"text": "Never Married"
},
"multipleBirthBoolean": false,
"communication": [
{
"language": {
"coding": [
{
"system": "http://hl7.org/fhir/ValueSet/languages",
"code": "en-US",
"display": "English (United States)"
}
]
}
}
],
"generalPractitioner": [
{
"reference": "urn:uuid:1a3711a3-1d38-4aeb-b25f-705ea922b1c2"
}
],
"resourceType": "Patient"
}
`)
/*var graphs []Graph
master := createMasterNode(&unmarshal)
graphs = append(graphs, master)*/
rules := map[string]map[string]interface{}{
"Patient": {
"generalPractitioner": "practitioner",
},
}
var unmarshal map[string]interface{}
err := json.Unmarshal(data, &unmarshal)
if err != nil {
panic(err)
}
resource := unmarshal["resourceType"].(string)
jsonInfo := models.JSONInfo{
DecodedJSON: unmarshal,
Rules: getRules(resource, rules),
Master: strings.ToLower(resource),
ID: unmarshal["id"].(string),
}
j := J.Jypher{}
graph := j.GetJypher(&jsonInfo)
data, _ = json.MarshalIndent(graph, " ", " ")
fmt.Println(string(data))
cypher := j.BuildCypher()
fmt.Println(cypher)
}
func getRules(resource string, rules map[string]map[string]interface{}) map[string]interface{} {
if rule, ok := rules[resource]; ok {
return rule
} else {
panic(fmt.Sprintf("Rules provided but rules for [%s] not found, check the rules dictionary", resource))
}
return nil
}
Decoded Graph model out of the JSON
{
"address0":{
"nodes":{
"lebel":"address0",
"properties":[
{
"city":"Sunderland"
},
{
"state":"MA"
},
{
"postalCode":"01375"
},
{
"country":"US"
}
]
},
"edges":{
"source":"patient",
"target":"address0"
}
},
"coding0":{
"nodes":{
"lebel":"coding0",
"properties":[
{
"system":"http://hl7.org/fhir/identifier-type"
},
{
"code":"SB"
}
]
},
"edges":{
"source":"type",
"target":"coding0"
}
},
"coding1":{
"nodes":{
"lebel":"coding1",
"properties":[
{
"system":"http://hl7.org/fhir/v3/MaritalStatus"
},
{
"code":"S"
}
]
},
"edges":{
"source":"maritalStatus",
"target":"coding1"
}
},
"coding4":{
"nodes":{
"lebel":"coding4",
"properties":[
{
"system":"http://hl7.org/fhir/ValueSet/languages"
},
{
"code":"en-US"
},
{
"display":"English (United States)"
}
]
},
"edges":{
"source":"language",
"target":"coding4"
}
},
"communication4":{
"nodes":{
"lebel":"communication4"
},
"edges":{
"source":"patient",
"target":"communication4"
}
},
"identifier0":{
"nodes":{
"lebel":"identifier0",
"properties":[
{
"system":"http://hl7.org/fhir/sid/us-ssn"
},
{
"value":"999608294"
}
]
},
"edges":{
"source":"patient",
"target":"identifier0"
}
},
"language":{
"nodes":{
"lebel":"language"
},
"edges":{
"source":"communication4",
"target":"language"
}
},
"maritalStatus":{
"nodes":{
"lebel":"maritalStatus",
"properties":[
{
"text":"Never Married"
}
]
},
"edges":{
"source":"patient",
"target":"maritalStatus"
}
},
"meta":{
"nodes":{
"lebel":"meta"
},
"edges":{
"source":"patient",
"target":"meta"
}
},
"name1":{
"nodes":{
"lebel":"name1",
"properties":[
{
"use":"official"
},
{
"family":"Abernathy691"
}
]
},
"edges":{
"source":"patient",
"target":"name1"
}
},
"patient":{
"nodes":{
"id":"49c2df26-6fb9-43fb-82a2-3bd413a95934",
"lebel":"patient",
"properties":[
{
"resourceType":"Patient"
},
{
"id":"49c2df26-6fb9-43fb-82a2-3bd413a95934"
},
{
"gender":"female"
},
{
"birthDate":"2004-09-12"
}
]
},
"edges":{
"source":"patient",
"target":"patient"
}
},
"practitioner3":{
"nodes":{
"id":"urn:uuid:1a3711a3-1d38-4aeb-b25f-705ea922b1c2",
"lebel":"practitioner3",
"properties":[
{
"reference":"urn:uuid:1a3711a3-1d38-4aeb-b25f-705ea922b1c2"
}
]
},
"edges":{
"source":"patient",
"target":"practitioner3"
}
},
"telecom2":{
"nodes":{
"lebel":"telecom2",
"properties":[
{
"value":"1-892-670-6907 x741"
},
{
"use":"home"
},
{
"system":"phone"
}
]
},
"edges":{
"source":"patient",
"target":"telecom2"
}
},
"type":{
"nodes":{
"lebel":"type"
},
"edges":{
"source":"identifier0",
"target":"type"
}
}
}
Generated CYPHER QUERY
MERGE (patient:Patient {id:'49c2df26-6fb9-43fb-82a2-3bd413a95934'}) ON CREATE SET patient.resourceType = 'Patient', patient.id = '49c2df26-6fb9-43fb-82a2-3bd413a95934', patient.gender = 'female', patient.birthDate = '2004-09-12'
CREATE (identifier0:Identifier) SET identifier0.system = 'http://hl7.org/fhir/sid/us-ssn', identifier0.value = '999608294', identifier0._id = '49c2df26-6fb9-43fb-82a2-3bd413a95934'
MERGE (patient)-[:PATIENT_IDENTIFIER]->(identifier0)
CREATE (type:Type) SET type._id = '49c2df26-6fb9-43fb-82a2-3bd413a95934'
MERGE (identifier0)-[:IDENTIFIER0_TYPE]->(type)
CREATE (coding0:Coding) SET coding0.system = 'http://hl7.org/fhir/identifier-type', coding0.code = 'SB', coding0._id = '49c2df26-6fb9-43fb-82a2-3bd413a95934'
MERGE (type)-[:TYPE_CODING]->(coding0)
CREATE (name1:Name) SET name1.use = 'official', name1.family = 'Abernathy691', name1._id = '49c2df26-6fb9-43fb-82a2-3bd413a95934'
MERGE (patient)-[:PATIENT_NAME]->(name1)
CREATE (telecom2:Telecom) SET telecom2.value = '1-892-670-6907 x741', telecom2.use = 'home', telecom2.system = 'phone', telecom2._id = '49c2df26-6fb9-43fb-82a2-3bd413a95934'
MERGE (patient)-[:PATIENT_TELECOM]->(telecom2)
MERGE (practitioner3:Practitioner {id:'urn:uuid:1a3711a3-1d38-4aeb-b25f-705ea922b1c2'}) ON CREATE SET practitioner3.reference = 'urn:uuid:1a3711a3-1d38-4aeb-b25f-705ea922b1c2'
MERGE (patient)-[:PATIENT_PRACTITIONER]->(practitioner3)
CREATE (communication4:Communication) SET communication4._id = '49c2df26-6fb9-43fb-82a2-3bd413a95934'
MERGE (patient)-[:PATIENT_COMMUNICATION]->(communication4)
CREATE (language:Language) SET language._id = '49c2df26-6fb9-43fb-82a2-3bd413a95934'
MERGE (communication4)-[:COMMUNICATION4_LANGUAGE]->(language)
CREATE (coding4:Coding) SET coding4.system = 'http://hl7.org/fhir/ValueSet/languages', coding4.code = 'en-US', coding4.display = 'English (United States)', coding4._id = '49c2df26-6fb9-43fb-82a2-3bd413a95934'
MERGE (language)-[:LANGUAGE_CODING]->(coding4)
CREATE (meta:Meta) SET meta._id = '49c2df26-6fb9-43fb-82a2-3bd413a95934'
MERGE (patient)-[:PATIENT_META]->(meta) CREATE (address0:Address) SET address0.city = 'Sunderland', address0.state = 'MA', address0.postalCode = '01375', address0.country = 'US', address0._id = '49c2df26-6fb9-43fb-82a2-3bd413a95934'
MERGE (patient)-[:PATIENT_ADDRESS]->(address0)
CREATE (maritalStatus:MaritalStatus) SET maritalStatus.text = 'Never Married', maritalStatus._id = '49c2df26-6fb9-43fb-82a2-3bd413a95934'
MERGE (patient)-[:PATIENT_MARITALSTATUS]->(maritalStatus) CREATE (coding1:Coding) SET coding1.system = 'http://hl7.org/fhir/v3/MaritalStatus', coding1.code = 'S', coding1._id = '49c2df26-6fb9-43fb-82a2-3bd413a95934'
MERGE (maritalStatus)-[:MARITALSTATUS_CODING]->(coding1)
Sample Output Graph
- Create separate Node with Array of String
- Serialization of Query Generation for better Execution of Cypher
- Remove id field from properties of master node
- multiple identifier in a array list with same type of field name , right now it skips and takes only one