Skip to content

Latest commit

 

History

History
435 lines (399 loc) · 11.3 KB

README.md

File metadata and controls

435 lines (399 loc) · 11.3 KB

JSON to CYPHER QUERY Generator (Jypher)

Go Report Card

Important Components

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

Graph

Todo

  • Create separate Node with Array of String
  • Serialization of Query Generation for better Execution of Cypher
  • Remove id field from properties of master node

Limitation

  • multiple identifier in a array list with same type of field name , right now it skips and takes only one