web stats
HL7 2.x to JSON DB field - Mirth Community

Go Back   Mirth Community > Mirth Connect > Support

Reply
 
Thread Tools Display Modes
  #1  
Old 01-26-2015, 12:32 AM
fluancefg fluancefg is offline
OBX.2 Kenobi
 
Join Date: Oct 2013
Posts: 83
fluancefg is on a distinguished road
Default HL7 2.x to JSON DB field

Hi,

I'm looking for the best way to store the HL7 data we receive in input into a JSON field in PostgreSQL.
Our goal is to store the data with the original structure, like the example below:

{
"MSH": {
"MSH.1": "|",
"MSH.2": "^~\\&",
"MSH.3": {
"MSH.3.1": "SwiSyn",
"MSH.3.2": "General"
}, ...

I've read different posts about JSON, but it is not clear if we may use the intergrated Rhino JSON parser to do that or if we have to convert from XML to JSON, for example with json-lib.

http://www.mirthcorp.com/community/f...highlight=json
http://www.mirthcorp.com/community/f...highlight=json

I've also read MIRTH-2276 and MIRTH-2759 about JSON data type, but unfortunately we can't wait until it will be available.

Any advice on how to achieve that would be very useful.

Thank you
Reply With Quote
  #2  
Old 01-27-2015, 05:45 AM
narupley's Avatar
narupley narupley is online now
Mirth Employee
 
Join Date: Oct 2010
Posts: 7,111
narupley is on a distinguished road
Default

That should be very easy to do, and yes you would use the built-in Rhino parser. Iterate through all the nodes within msg, and add nodes to a JavaScript object. Then at the end, you just call JSON.stringify.
__________________
Step 1: JAVA CACHE...DID YOU CLEAR ...wait, ding dong the witch is dead?

Nicholas Rupley
Work: 949-237-6069
Always include what Mirth Connect version you're working with. Also include (if applicable) the code you're using and full stacktraces for errors (use CODE tags). Posting your entire channel is helpful as well; make sure to scrub any PHI/passwords first.


- How do I foo?
- You just bar.
Reply With Quote
  #3  
Old 01-29-2015, 07:02 AM
fluancefg fluancefg is offline
OBX.2 Kenobi
 
Join Date: Oct 2013
Posts: 83
fluancefg is on a distinguished road
Default

Ok, thank your for the advice. Based on your suggestion and one of your other post with an example on how to "walk the HL7 DOM" in its entirety, I've done it like that:

Code:
var jsonobj = {};

for each (segment in msg.children()) {
	if (segment.hasComplexContent()) {
		var seg = {};
		for each (field in segment.children()) {
			if (field.hasComplexContent()) {
				var fd = {};
				for each (component in field.children()) {
					if (component.hasComplexContent()) {
						var comp = {};
						for each (subcomponent in component.children()) {
							comp[subcomponent.name()] = getElementDatatype(subcomponent);
						}
						fd[component.name()] = comp;
					} else {
						fd[component.name()] = getElementDatatype(component);
					}
				}
				seg[field.name()] = fd;
			} else {
				seg[field.name()] = getElementDatatype(field);
			}
		}
		jsonobj[segment.name()] = seg;
	} else {
		jsonobj[segment.name()] = getElementDatatype(segment);
	}
}

JSON.stringify(jsonobj);
The getElementDatatype just returns a Number, Boolean or String object or null if it's empty.
Reply With Quote
  #4  
Old 01-29-2015, 07:34 AM
narupley's Avatar
narupley narupley is online now
Mirth Employee
 
Join Date: Oct 2010
Posts: 7,111
narupley is on a distinguished road
Default

Nice, that's slick.

The only suggestion I'd have is to only use the segment name, and use arrays for everything underneath. For example, instead of this:

Code:
{
	"PID" : {
		"PID.1" : {
			"PID.1.1" : 1
		},
		"PID.2" : {
			"PID.2.1" : 1001
		},
		"PID.3" : {
			"PID.3.1" : 1001,
			"PID.3.2" : 5,
			"PID.3.3" : {
				"PID.3.3.1" : "M11",
				"PID.3.3.2" : "M12",
				"PID.3.3.3" : "M13"
			},
			"PID.3.4" : "ADT1",
			"PID.3.5" : "MR"
		},
		"PID.3" : {
			"PID.3.1" : 123456789,
			"PID.3.2" : "",
			"PID.3.3" : {
				"PID.3.3.1" : "S11",
				"PID.3.3.2" : "S12",
				"PID.3.3.3" : "S13"
			},
			"PID.3.4" : "USSSA",
			"PID.3.5" : "SS"
		},

		...
	},

	...
}
More like this:

Code:
{
	"PID" : [
		1,
		1001,
		[
			1001,
			5,
			[
				"M11",
				"M12",
				"M13"
			],
			"ADT1",
			"MR"
		],
		[
			123456789,
			"",
			[
				"S11",
				"S12",
				"S13"
			],
			"USSSA",
			"SS"
		],

		...
	],

	...
}
If you minify both of them, the first example has 342 characters, whereas the second example has 113 characters. Over the course of an entire HL7 message (especially larger messages), that could significantly cut down on the amount of data you're storing / parsing.

Anyway just a thought, your method works perfectly fine as well.
__________________
Step 1: JAVA CACHE...DID YOU CLEAR ...wait, ding dong the witch is dead?

Nicholas Rupley
Work: 949-237-6069
Always include what Mirth Connect version you're working with. Also include (if applicable) the code you're using and full stacktraces for errors (use CODE tags). Posting your entire channel is helpful as well; make sure to scrub any PHI/passwords first.


- How do I foo?
- You just bar.
Reply With Quote
  #5  
Old 01-30-2015, 05:58 AM
fluancefg fluancefg is offline
OBX.2 Kenobi
 
Join Date: Oct 2013
Posts: 83
fluancefg is on a distinguished road
Default

What a good thought ! My lack of experience with JSON has not permitted to think about that.
Small changes with a great gain. As we process thousand of files per week, the advantage might be non negligible.
For whom might be interested:
Code:
var jsonobj = {};

for each (segment in msg.children()) {
	if (segment.hasComplexContent()) {
		var seg = [];
		for each (field in segment.children()) {
			if (field.hasComplexContent()) {
				var fd = [];
				for each (component in field.children()) {
					if (component.hasComplexContent()) {
						var comp = [];
						for each (subcomponent in component.children()) {
							comp.push(getElementDatatype(subcomponent));
						}
						fd.push(comp);
					} else {
						fd.push(getElementDatatype(component));
					}
				}
				seg.push(fd);
			} else {
				seg.push(getElementDatatype(field));
			}
		}
		jsonobj[segment.name()] = seg;
	} else {
		jsonobj[segment.name()] = getElementDatatype(segment);
	}
}

JSON.stringify(jsonobj);
Thank you very much.
Reply With Quote
  #6  
Old 02-03-2015, 03:08 AM
fluancefg fluancefg is offline
OBX.2 Kenobi
 
Join Date: Oct 2013
Posts: 83
fluancefg is on a distinguished road
Default

I've found a disadvantage in this solution. Because the json array are indexed starting with 0, you'll have to access the desired data in an inconvenient way, e.g.

to get PV1.19.1: SELECT hl7_data#>'{PV1, 18, 0}'

This may be somehow confusing.

Last edited by fluancefg; 02-03-2015 at 04:58 AM.
Reply With Quote
  #7  
Old 02-03-2015, 06:24 AM
narupley's Avatar
narupley narupley is online now
Mirth Employee
 
Join Date: Oct 2010
Posts: 7,111
narupley is on a distinguished road
Default

True, though if you're worried about that, you can just always add an empty element to the start of your arrays.
__________________
Step 1: JAVA CACHE...DID YOU CLEAR ...wait, ding dong the witch is dead?

Nicholas Rupley
Work: 949-237-6069
Always include what Mirth Connect version you're working with. Also include (if applicable) the code you're using and full stacktraces for errors (use CODE tags). Posting your entire channel is helpful as well; make sure to scrub any PHI/passwords first.


- How do I foo?
- You just bar.
Reply With Quote
  #8  
Old 02-13-2015, 02:46 AM
fluancefg fluancefg is offline
OBX.2 Kenobi
 
Join Date: Oct 2013
Posts: 83
fluancefg is on a distinguished road
Default

I've found a problem when dealing with repeatable segments. For example, with this STF segment which has two STF.2 fields, the first one is correctly identified with the STF.2 field, but the second is identified with STF.3 field number:

STF|2140^JANSSENS Jean-Paul|2140~7601000033598^^^EAN|

Any idea on how to deal with that ?

Thank you

Last edited by fluancefg; 02-13-2015 at 03:52 AM.
Reply With Quote
  #9  
Old 02-13-2015, 06:46 AM
narupley's Avatar
narupley narupley is online now
Mirth Employee
 
Join Date: Oct 2010
Posts: 7,111
narupley is on a distinguished road
Default

In your field loop you could probably store the field name, and then on each iteration check if the current field name is equal to the previous field name. That way you'd know when you've encountered a repetition.
__________________
Step 1: JAVA CACHE...DID YOU CLEAR ...wait, ding dong the witch is dead?

Nicholas Rupley
Work: 949-237-6069
Always include what Mirth Connect version you're working with. Also include (if applicable) the code you're using and full stacktraces for errors (use CODE tags). Posting your entire channel is helpful as well; make sure to scrub any PHI/passwords first.


- How do I foo?
- You just bar.
Reply With Quote
  #10  
Old 02-26-2015, 02:17 AM
fluancefg fluancefg is offline
OBX.2 Kenobi
 
Join Date: Oct 2013
Posts: 83
fluancefg is on a distinguished road
Default

With the field name I was able to handle the repeatable segments and to put them in an array.

Thank you
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -8. The time now is 11:40 AM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Mirth Corporation