Zusammenfassung
Bislang gibt es kein Allheilmittel für den Aufbau einer funktionierenden ETL-Pipeline zur Übertragung eines HL7v2-Nachrichten-Feeds aus einem EHR in FHIR-Daten – und das gilt auch für MatrixCare EHR, sobald Anpassungsmöglichkeiten ins Spiel kommen. In diesem Artikel zeigen wir anhand von Beispielen, wie wir die Integrationsprobleme gelöst haben und welche Werkzeuge wir dabei eingesetzt haben (Spoiler: Aidbox). Außerdem beschreiben wir die grundlegenden Prinzipien der HL7v2-zu-FHIR-Systemkonfiguration – zum Nutzen all jener, die ihr eigenes System von Grund auf aufbauen möchten.
FHIR-Daten sind ein ideales Informationsmodell für:
- Datenaggregation für weiterführende Analysen;
- die Schaffung eines FHIR-App-Stores für das Gesundheitswesen und die Bereitstellung von Daten für Smart Apps;
- die schrittweise Weiterentwicklung der bestehenden Anwendung oder die Suche nach individuellen Lösungen für spezielle Aufgaben.
Um Ihnen einen kurzen Überblick über das Gesamtsystem zu verschaffen, sehen Sie sich bitte dieses Diagramm an, das die vollständige ETL-Pipeline für MatrixCare EHR von Health Samurai zeigt:

Allgemeine Architektur
In diesem Beitrag besprechen wir MatrixCare EHR, obwohl aufmerksame Leserinnen und Leser möglicherweise bemerken werden, dass die beschriebene Erfahrung vollständig auf jedes andere EHR übertragbar ist – denn nahezu jedes System, das für die Ausführung einer effektiven ETL-Pipeline entwickelt wurde, arbeitet nach denselben Prinzipien.
Die Übernahme von Daten aus einer externen Quelle beginnt also mit der QUELLE dieser Daten!
Datenquelle

Unsere Datenquelle ist MatrixCare EHR. Es erzeugt RAW HL7v2-Nachrichten. Falls Sie vergessen haben oder nicht wissen, wie rohe HL7v2-Nachrichten aussehen, hier ein kurzes Beispiel. Es handelt sich um ein recht altes Datenformat, das im Wesentlichen aus einer Zeichenkette besteht, die in Segmente (und Untersegmente) unterteilt ist, wobei jedes davon nützliche medizinische Informationen speichert.
Zeichenketten sind nicht der praktischste Datentyp, weshalb sie üblicherweise in für Menschen und Maschinen lesbare Datenstrukturen (JSON, YAML oder EDN) geparst werden. Es gibt Open-Source-Parser für HL7v2-Nachrichten (z. B. v2 to FHIR, HL7v2 to FHIR converter by Linux For Health), jedoch bietet Aidbox eine integrierte Funktion zum Parsen von Nachrichten und zur persistenten Speicherung des Ergebnisses.
Unsere Quelle erzeugt eine große Anzahl von HL7v2-Nachrichten wie diese:

MatrixCare EHR sendet eine ADT-Nachricht (Admit, Discharge, Transfer) im HL7v2-Format. Es verwendet Version 2.5 des HL7-Standards. Eine Nachricht besteht aus folgenden Segmenten:
- MSH (Message Header), NK1 (Next of Kin), AL1 (Allergies), DG1 (Diagnosis), PV1 (Patient Visit), PV2 (Patient Visit Additional), GT1 (Guarantor)
- Für jedes Segment gibt es eine umfassende Dokumentation, z. B.: https://hl7-definition.caristix.com/v2/HL7v2.5.1/Segments/MSH
Warteschlange

Es ist kaum vorstellbar, ein komplexes System ohne Datenstrukturen zu betreiben, die einen geordneten Zugriff ermöglichen. Medizinische Systeme verwenden Warteschlangen für folgende Zwecke:
- Verzögerte Verarbeitung – niemand erwartet, dass alle Systeme alle eingehenden Daten sofort verarbeiten; es genügt zu wissen, dass dies zu einem vorhersehbaren Zeitpunkt in naher Zukunft geschehen wird;
- Skalierbarkeit – wir können weitere Consumer hinzufügen, um Daten schneller zu verarbeiten;
- Lastspitzen – wir können nicht davon ausgehen, dass der Datenfluss stets linear verläuft.
In unserem Beispiel verwenden wir Amazon SQS (obwohl wir unseren Application Adapter so konfigurieren können, dass er mit nahezu jedem Warteschlangendienst zusammenarbeitet). Amazon SQS verfügt über einige interessante Funktionen. Neben dem parallelen Zugriff, einem Deduplizierungsmechanismus, Long Polling und einer übersichtlichen Visualisierung gibt es eine Funktion, die uns am meisten überzeugt. Es handelt sich dabei um die DLQ oder Dead-Letter-Queue. Wenn beim Verarbeiten einer Nachricht etwas Unerwartetes passiert, versucht SQS, die Nachricht an den Consumer zuzustellen, aber nach mehreren Versuchen wird sie in der DLQ gespeichert, von wo aus sie manuell oder programmatisch verarbeitet werden kann (Spoiler: Ja, unsere Lilly Adapter-Anwendung verfügt über eine API zur Wiederverarbeitung von DLQ-Nachrichten – POST "/$sqs-dlq-reprocess").
Wo die Magie beginnt!

Nach der Extraktion der HL7v2-Nachricht müssen wir eine Transformation nach FHIR durchführen. Dafür haben wir tatsächlich eine Video-Anleitung:
Wie bereits erwähnt, gibt es verschiedene Open-Source-Parser für HL7v2, aber Aidbox bietet integrierte Funktionen, um die gesamte ETL-Pipeline abzudecken:
- Persistente Speicherung eingehender Nachrichten in der Datenbank (Aidbox DB https://www.health-samurai.io/docs/aidbox/storage-1/database), um Datenverlust oder Datenfehler zu vermeiden;
- Parsen der Nachricht in für Menschen und Maschinen lesbare Datenstrukturen (HL7v2-Parser https://www.health-samurai.io/docs/aidbox/modules-1/hl7-v2-integration);
- Parsen der Nachricht in FHIR-Daten mithilfe der JUTE-Mapping-Sprache (Data-DSL von Health Samurai https://github.com/HealthSamurai/jute.clj);
- Persistente Speicherung der erstellten FHIR-Ressourcen in einer Datenbank (wieder AidboxDB).
So läuft der Prozess genau ab:
- Lilly Adapter stellt einen Listener (oder Consumer) bereit, der kontinuierlich bei SQS nach neuen Nachrichten fragt und, sofern welche vorhanden sind, die Verarbeitung der HL7v2-Nachricht einleitet,
- neue eingehende HL7v2-Nachrichten werden in der HL7v2Message-Ressource gespeichert: src: "HL7V2MESSAGE" status: received
- Aidbox stellt einen Job bereit, der auf neue Nachrichten mit dem Status 'received' wartet,

- nachdem die Nachricht vom Aidbox-System erkannt wurde, wird sie von Aidbox geparst: Die rohe HL7v2-Nachricht wird in eine für Menschen lesbare Datenstruktur umgewandelt, die als YAML oder JSON zurückgegeben werden kann, und wird unter dem Schlüssel 'parsed' in derselben HL7v2Message-Ressource gespeichert:

- das Feld config muss ebenfalls unterstützt werden – config legt fest, welcher Satz von Mappings (mehr dazu unter https://www.health-samurai.io/docs/aidbox/tools/mappings) angewendet wird. Config wird in der HL7v2Config-Ressource gespeichert, Mappings werden als Mapping-Ressource gespeichert;
- die geparsten Daten sind also die Eingabedaten für die Mappings, und das Ergebnis der Mapping-Anwendung wird im Feld outcome gespeichert:
outcome = all_mappings_from_hl7v2config(parsed_field_data)
- Je nachdem, ob sowohl der Parse-Vorgang als auch die Ressourcenerstellung erfolgreich verlaufen, wird der Status der Nachricht von 'received' auf 'processed' geändert. Schlägt der Vorgang fehl, wird der Status 'error' vergeben. Die Lilly Adapter-Anwendung verfügt über eine API zur Nachrichtenwiederverarbeitung. Sie kann Nachrichten nach verschiedenen Kriterien wie Status, Ereignistyp, Zeitraum usw. erneut verarbeiten. Der Status 'processed' bedeutet, dass alle erforderlichen FHIR-Ressourcen erfolgreich erstellt wurden:

Ein wenig mehr zu den Mappings
Mappings erfüllen mehrere Funktionen:
- Sie ermöglichen die Transformation von geparsten Daten in ein Ergebnis (Outcome) gemäß der in den Mappings definierten benutzerdefinierten Logik;
- Sie stellen einen Mechanismus zur persistenten Datenspeicherung bereit (manche vertreten die Auffassung, dass FHIR für den Datenaustausch und nicht für die Datenspeicherung entwickelt wurde – wir sehen das jedoch anders: https://www.health-samurai.io/articles/should-you-use-fhir-resources-as-your-data-storage-format);
- Der Satz der auf das geparste Feld angewendeten Mappings wird über die HL7v2Config-Ressource konfiguriert, mehr dazu hier: https://www.health-samurai.io/docs/aidbox/modules-1/hl7-v2-integration.
Mappings werden in einer speziellen DSL geschrieben, die vom Health Samurai-Team entwickelt wurde – der JUTE-Mapping-Sprache. Es handelt sich um eine schlanke und gut dokumentierte DSL mit nahezu keiner Lernkurve, die so gestaltet ist, dass Sie nicht einmal Programmierkenntnisse benötigen, um Ihre Mappings zu schreiben. Dennoch werden Sie gelegentlich auf komplexe Fälle stoßen, die anspruchsvollere Mappings erfordern.
Link: https://github.com/HealthSamurai/jute.clj
Sie fragen sich vielleicht, wie die Anwendung von Mappings zur persistenten Datenspeicherung führt. Wir versuchen, das zu erklären:

Mappings müssen ein Feld 'request' enthalten, das tatsächlich einem Aidbox-API-Aufruf entspricht, der als Ergebnis der Mapping-Anwendung ausgeführt wird. Infolge der Mapping-Anwendung werden Ressourcen erstellt und in der Aidbox-Datenbank persistent gespeichert.
Um zu erkunden, wie Aidbox Ihre Integration mit MatrixCare EHR verbessern kann, testen Sie die kostenlose Version von Aidbox. Sie bietet eine vollständige Umgebung zum Testen und Verfeinern von Integrationsprozessen und stellt alle erforderlichen Werkzeuge ohne Funktionseinschränkungen bereit.
Zusammenfassung
Hier sind die Schritte, die Sie unternehmen müssen, um eine Integration mit MatrixCare einzurichten:
- Stellen Sie eine Instanz bereit, die Nachrichten von MatrixCare abruft (das kann nahezu jede Instanz sein, einschließlich Kafka oder RabbitMQ, aber wir haben hier Amazon SQS verwendet);
- finden Sie eine Möglichkeit, diese Nachricht zu verarbeiten (aus einer Warteschlange oder direkt vom EHR);
- parsen Sie die HL7v2-Nachricht von einer Zeichenkette in eine Datenstruktur;
- transformieren Sie das geparste HL7v2 in FHIR-Ressourcen;
- speichern Sie das Ergebnis.
Sie könnten das Rad zwar neu erfinden, aber Aidbox ist bereits so konfiguriert, dass die gesamte Magie in sich selbst stattfindet. Wir speichern Nachrichten persistent, parsen sie, übersetzen sie in das FHIR-Format und speichern dann das Ergebnis persistent. Wie Sie bemerkt haben mögen, ist die Adapter-Anwendung schlank, und Sie könnten durchaus Ihre eigene Version davon entwickeln – wir halten dies jedoch nicht für notwendig.
Mappings (die zur Transformation von Daten aus geparsten HL7v2-Nachrichten in FHIR-Ressourcen verwendet werden) sind ein Anpassungspunkt. Jedes EHR wird wahrscheinlich einen eigenen Satz von Mappings benötigen, aber wir haben auch einige vorgefertigte Mappings für MatrixCare EHR, die hilfreich sein könnten. Wir können an jedem Punkt des Integrationsprozesses Unterstützung leisten.
Autor: Artem Alexeev
Siehe auch: Umgang mit der Integration von Altsystemen.






