Wie soll man unter Zehntausenden die richtige finden?
Gemeint sind natürlich CPTs, bei denen es sich um standardisierte Codes zur genauen Identifizierung von diagnostischen, chirurgischen und anderen medizinischen Prozeduren handelt. Und jedes Mal, wenn ein Arzt bei uns einen Entlasssbrief schreibt, muss er dazu die richtigen CPT-Codes angeben, so will es das Ministerium.
Bis gestern gab es dazu in unserem System eine Auswahlbox die so aussah:
Zwar war eine Volltextsuche möglich, doch in der Praxis gab es einige Probleme:
- Es gibt oft mehrere ähnliche Codes für die gleiche Behandlung. Der Arzt muss die ganze Beschreibung lesen, um den richtigen auszuwählen, was bei dem kleinen Auswahlfeld quasi unmöglich ist. Niemand möchte den weiten und beschwerlichen Weg bis zum unteren Ende der Trefferliste auf sich nehmen.
- Es fehlt der Überblick darüber, welche Codes es überhaupt gibt.
- Die Codes sind eigentlich hierarchisch nach Kategorien geordnet. Doch davon kann der Benutzer gar keinen Gebrauch machen. Dadurch wurden manchmal Codes ausgewählt, die zwar ähnlich anmuten, aber zu einer anderen Spezialisierung als der des Arztes gehören. Und das gab dann Ärger mit dem Ministerium.
Tatsächlich habe ich die Trefferbox, die ich gerade kritisiere vor einigen Monaten selbst eingerichtet. Das war jedoch unter der (nichtzutreffenden) Annahme, dass die Ärzte die meisten Codes ohnehin auswendig wissen und die Beschreibung eher der Kontrolle dient.
Erbeten wurde eine Verbesserung der Benutzerschnittstelle und aus dem Gespräch kristallisierten sich die folgenden Anforderungen heraus:
- Nach wie vor muss ein dem Arzt bekannter Code schnell ausgewählt werden können.
- Die Verortung in der hierarchischen Struktur muss dem Arzt bei der Auswahl eines Codes bewusst sein.
- Bei der Volltextsuche muss ein besserer Überblick über die Suchergebnisse hergestellt werden.
Gemeinsam mit meiner Kollegin wurde erst mal auf dem Papier eine grobe Idee entwickelt:
Die verfügbaren Codes sollten in Form eines auf- und zuklappbaren Baumes dargestellt werden.
Ein darüber befindliches Suchfeld sollte diesen Baum filtern.
Im Falle hinreichend vorgefilterter Ergebnisse sollte der gefilterte Baum sich bereits von Anfang an komplett aufklappen.
Ich nehme für die weniger technischen Leser das Ergebnis vorweg:
Im Video wird nach dem Stichwort „Hysterektomie“ gesucht. Bei diesem Beispiel wird an der schieren Menge der Ergebnisse sofort der Vorteil der Umstellung klar. Sofort kann die einzig verfügbare Anästhesie ausgewählt werden und auch im Bereich der Chirurgie ist es durch die Anzeige der Beschreibungen in langen Zeilen nun möglich, die richtige Variante auszuwählen (die davon abhängt, welche Operationsmethode angewandt wurde, welche Organe mit entfernt wurden und wie schwer die entfernten Organe waren).
Nun zum Technischen. Interessant wurde die Umsetzung aus folgenden Gründen:
- Der gesamte Baum ist zu groß, um ihn in seiner Fülle dem Browser zuzumuten. Es werden immer nur die gerade aufgeklappten Schichten, beziehungsweise das aktuelle Suchergebnis per AJAX vom Server angefordert. Auch der gefilterte Baum wird nur dann komplett geladen, wenn die Suche hinreichend genau war.
- Obwohl für den Benutzer der Eindruck erweckt wird, dass beim Tippen die Suche sofort verfeinert wird, stoßen die einzelnen Tastenanschläge keine aufwendigen Anfragen aus, sondern erst wenn er mit dem Tippen aufhört (debouncing), wird nach 250ms eine Suche ausgelöst. Das führt im Test beim nicht flüssigen Tippen von „Hysterektomie“ zu nur zwei statt dreizehn Anfragen.
- Der Baum wird nicht bei jeder Anfrage erneut aus der Datenbank geladen und zusammengesetzt, sondern in einer optimierten Hash-basierten Datenstruktur im Arbeitsspeicher gecached und dann nur in Echtzeit gefiltert, der passende Teilbaum ausgewählt und dann der Baum an der maximalen Tiefe beschnitten.
- Die Tiefe des Baumes ist technisch (weitgehend) unbegrenzt. Sollte das Ministerium eine 20 Ebenen tiefe Verschachtelung vorsehen, sind wir schon gewappnet.
- Der Baumfilteralgorithmus ist interessant. Durch die Suchbegriffe wird die Teilmenge der anzuzeigenden Blätter festgelegt. Nun ist ein minimaler Teilbaum gesucht, der alle diese Blätter enthält (aber keine leergefilterten Unterkategorien). Das performant und richtig zu bewerkstelligen erforderte zwei Anläufe. Und ich konnte meiner Kollegin dabei Unit-Tests erklären.
- Spezialbehandlung von Sonderzeichen: Wer ‚i‘ eingibt, möchte auch Treffer finden, die ‚í‘ (mit Akzent) enthalten. Rein technisch sind das aber erst einmal völlig verschiedene Zeichen. Dass dies nötig ist, war die Idee meiner neuen peruanischen Kollegin.
- Die Baumalgorithmen im Backend wie auch das von Grund auf selbst entwickelte jQuery-Plugin zur dynamischen Baumanzeige im Frontend wurden als wiederverwendbare Komponenten angelegt.
Diese „Klickibunti“-Arbeit hat mir viel Freude bereitet, weil man am Ende das Ergebnis so schön sieht.
Und vielleicht hilft er auch bei der Beantwortung der folgenden Frage:
Was hat dieser Informatiker eigentlich in einem Missionskrankenhaus zu suchen?