Skip to content

JSON to CYPHER QUERY Generator for Neo4j Graph Database

License

Notifications You must be signed in to change notification settings

restra-social/jypher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

About

JSON to CYPHER QUERY Generator for Neo4j Graph Database

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages