1
0

Update howto-fhir-date-parameter.md

This commit is contained in:
hmk
2026-08-12 13:01:12 +00:00
parent 503311311f
commit 1d9d08957a
+66 -23
View File
@@ -5,7 +5,44 @@ Wer FHIR-Server baut oder abfragt, stolpert früher oder später über den
`?date=2023-06-15` aber sobald Präfixe wie `ge`, `sa` oder `ap` ins Spiel `?date=2023-06-15` aber sobald Präfixe wie `ge`, `sa` oder `ap` ins Spiel
kommen und mehrere `date`-Parameter kombiniert werden, wird es schnell kommen und mehrere `date`-Parameter kombiniert werden, wird es schnell
unübersichtlich. Dieser Artikel bringt Ordnung rein: Schritt für Schritt, mit unübersichtlich. Dieser Artikel bringt Ordnung rein: Schritt für Schritt, mit
Zeitleisten-Grafiken zu jedem Fall. Zeitleisten-Grafiken zu jedem Fall — und als Kurzreferenz zum schnellen
Nachschlagen.
## Inhaltsverzeichnis
- [Kurzreferenz: Alle Präfixe auf einen Blick](#kurzreferenz-alle-präfixe-auf-einen-blick)
- [1. Das Grundprinzip: FHIR vergleicht Intervalle, keine Zeitpunkte](#1-das-grundprinzip-fhir-vergleicht-intervalle-keine-zeitpunkte)
- [2. Die neun Präfixe im Überblick](#2-die-neun-präfixe-im-überblick)
- [3. Matching gegen `Period` und `Range`](#3-matching-gegen-period-und-range)
- [4. Offene (unvollständige) Periods](#4-offene-unvollständige-periods)
- [5. Mehrere `date`-Parameter kombinieren](#5-mehrere-date-parameter-kombinieren)
- [6. Die vollständige 3×3-Matrix aller Bereichs-Kombinationen](#6-die-vollständige-3×3-matrix-aller-bereichs-kombinationen)
- [7. Sonderfälle: redundant oder widersprüchlich](#7-sonderfälle-wenn-kombinationen-redundant-oder-widersprüchlich-werden)
- [8. Praxis-Empfehlungen zum Schluss](#8-praxis-empfehlungen-zum-schluss)
---
## Kurzreferenz: Alle Präfixe auf einen Blick
Für den schnellen Blick zwischendurch — Details und Grafiken zu jeder Zeile
folgen in den Abschnitten unten.
| Präfix | Name | Kurzregel | Beispiel |
|---|---|---|---|
| *(keins)* | implizit `eq` | Precision des Werts bestimmt das Intervall | `date=2023-06-15` |
| `eq` | gleich | Resource-Intervall vollständig im Such-Intervall | `date=eq2023-06-15` |
| `ne` | ungleich | Komplement von `eq` | `date=ne2023-06-15` |
| `gt` | größer als | Ragt über das Ende hinaus (Overlap genügt) | `date=gt2023-06-15` |
| `lt` | kleiner als | Beginnt vor dem Anfang (Overlap genügt) | `date=lt2023-06-15` |
| `ge` | größer/gleich | `gt` oder vollständig enthalten (`eq`) | `date=ge2023-06-15` |
| `le` | kleiner/gleich | `lt` oder vollständig enthalten (`eq`) | `date=le2023-06-15` |
| `sa` | starts after | Vollständig danach, **keine** Überlappung | `date=sa2023-06-15` |
| `eb` | ends before | Vollständig davor, **keine** Überlappung | `date=eb2023-06-15` |
| `ap` | approximately | Überlappung + ähnliche Größenordnung | `date=ap2023-06-15` |
**Fehlender `start`/`end` bei `Period`:** fehlender `start` = `-∞`, fehlendes
`end` = `+∞``sa` kann bei fehlendem `start` nie matchen, `eb` kann bei
fehlendem `end` nie matchen (Details in [Abschnitt 4](#4-offene-unvollständige-periods)).
--- ---
@@ -69,7 +106,7 @@ die jeweilige Grenze hinausragt. Details dazu im nächsten Abschnitt.
--- ---
## 3. Sonderfall: Matching gegen `Period` und `Range` ## 3. Matching gegen `Period` und `Range`
Die Grafiken oben zeigen das Resource-Datum als schmalen roten Marker das Die Grafiken oben zeigen das Resource-Datum als schmalen roten Marker das
passt für einfache `date`/`dateTime`-Felder wie `Patient.birthDate`. Sobald passt für einfache `date`/`dateTime`-Felder wie `Patient.birthDate`. Sobald
@@ -86,6 +123,12 @@ Unterscheidung zwischen **Containment** (vollständiges Enthaltensein) und
- **`sa` / `eb`** verlangen das Gegenteil von Overlap: das Resource-Intervall - **`sa` / `eb`** verlangen das Gegenteil von Overlap: das Resource-Intervall
muss vollständig und ohne jede Überlappung auf der jeweiligen Seite liegen. muss vollständig und ohne jede Überlappung auf der jeweiligen Seite liegen.
Bei einem einfachen Zeitpunkt-Feld (kein `Period`) fällt dieser Unterschied
praktisch nicht auf, da Resource-Start und -Ende (fast) identisch sind — dort
verhalten sich `gt` und `sa` de facto gleich. Der Unterschied wird erst bei
echten Zeitspannen relevant. Das ist auch der Grund, warum `sa`/`eb`
laut Spezifikation in erster Linie für `Period`/`Range`-Werte gedacht sind.
**Beispiel:** Ein Encounter läuft vom 10. bis 20. Juni. Die Suche **Beispiel:** Ein Encounter läuft vom 10. bis 20. Juni. Die Suche
`date=gt2023-06-15` soll ihn finden, obwohl der Encounter *vor* dem 15. `date=gt2023-06-15` soll ihn finden, obwohl der Encounter *vor* dem 15.
begonnen hat — entscheidend ist nur, dass er über den 15. hinausreicht begonnen hat — entscheidend ist nur, dass er über den 15. hinausreicht
@@ -112,7 +155,9 @@ komplett auf der richtigen Seite liegt, zählt dort.
| 16.20. Juni (komplett danach) | ✅ Treffer | ✅ Treffer | | 16.20. Juni (komplett danach) | ✅ Treffer | ✅ Treffer |
| 01.10. Juni (komplett davor) | ❌ kein Treffer | ❌ kein Treffer | | 01.10. Juni (komplett davor) | ❌ kein Treffer | ❌ kein Treffer |
### Offene (unvollständige) Periods ---
## 4. Offene (unvollständige) Periods
In der Praxis sind Periods oft **nicht abgeschlossen** — z. B. ein laufender In der Praxis sind Periods oft **nicht abgeschlossen** — z. B. ein laufender
Encounter ohne `end`, oder ein importierter Datensatz mit unbekanntem Encounter ohne `end`, oder ein importierter Datensatz mit unbekanntem
@@ -136,8 +181,8 @@ Das hat spürbare Konsequenzen, gerade für `sa` und `eb`:
overlap-basierten Filter (`gt`, `lt`, `ge`, `le`) — sie „reicht" ja per overlap-basierten Filter (`gt`, `lt`, `ge`, `le`) — sie „reicht" ja per
Definition über jede Grenze hinaus. Definition über jede Grenze hinaus.
Dieselben vier Präfixe wie oben, jetzt mit offenen statt geschlossenen Dieselben vier Präfixe wie in [Abschnitt 3](#3-matching-gegen-period-und-range),
Periods: jetzt mit offenen statt geschlossenen Periods:
![Offene Periods Matching](fhir-date-offene-periods.svg) ![Offene Periods Matching](fhir-date-offene-periods.svg)
@@ -147,15 +192,9 @@ willst, reicht `eb`/`sa` allein nicht — du musst zusätzlich nach dem Status
oder explizit nach `end:missing=true`/`start:missing=true` filtern, je oder explizit nach `end:missing=true`/`start:missing=true` filtern, je
nachdem, was dein Server unterstützt. nachdem, was dein Server unterstützt.
Bei einem einfachen Zeitpunkt-Feld (kein `Period`) fällt dieser Unterschied
praktisch nicht auf, da Resource-Start und -Ende (fast) identisch sind — dort
verhalten sich `gt` und `sa` de facto gleich. Der Unterschied wird erst bei
echten Zeitspannen relevant. Das ist auch der Grund, warum `sa`/`eb`
laut Spezifikation in erster Linie für `Period`/`Range`-Werte gedacht sind.
--- ---
## 4. Mehrere `date`-Parameter kombinieren ## 5. Mehrere `date`-Parameter kombinieren
In der Praxis reicht ein einzelner Präfix selten meist willst du einen In der Praxis reicht ein einzelner Präfix selten meist willst du einen
**Bereich** definieren. FHIR-Server verknüpfen mehrere `date`-Parameter in **Bereich** definieren. FHIR-Server verknüpfen mehrere `date`-Parameter in
@@ -176,7 +215,7 @@ klassischen Zeitfenster-Queries in SQL.
--- ---
## 5. Die vollständige 3×3-Matrix aller Bereichs-Kombinationen ## 6. Die vollständige 3×3-Matrix aller Bereichs-Kombinationen
Die vier Muster oben sind nur die gebräuchlichsten. Tatsächlich lässt sich Die vier Muster oben sind nur die gebräuchlichsten. Tatsächlich lässt sich
**jede** Untergrenze mit **jeder** Obergrenze kombinieren: **jede** Untergrenze mit **jeder** Obergrenze kombinieren:
@@ -197,7 +236,7 @@ gültige, funktionierende Query.
--- ---
## 6. Sonderfälle: Wenn Kombinationen redundant oder widersprüchlich werden ## 7. Sonderfälle: Wenn Kombinationen redundant oder widersprüchlich werden
Nicht jede syntaktisch gültige Kombination ist auch praktisch sinnvoll. Drei Nicht jede syntaktisch gültige Kombination ist auch praktisch sinnvoll. Drei
Kategorien solltest du kennen, bevor du sie versehentlich in einer Kategorien solltest du kennen, bevor du sie versehentlich in einer
@@ -233,21 +272,25 @@ Rückmeldung. Es lohnt sich, so etwas clientseitig vorab zu validieren.
--- ---
## 7. Praxis-Empfehlungen zum Schluss ## 8. Praxis-Empfehlungen zum Schluss
- Für einfache Bereichsfilter ist **`ge` + `lt`** (halboffenes Intervall) meist - Für einfache Bereichsfilter ist **`ge` + `lt`** (halboffenes Intervall) meist
das robusteste Muster es vermeidet Rundungsprobleme an der das robusteste Muster es vermeidet Rundungsprobleme an der
Precision-Grenze (kein Off-by-one bei „bis einschließlich 31.12."). Precision-Grenze (kein Off-by-one bei „bis einschließlich 31.12.").
- **`sa`/`eb`** bewusst einsetzen, wenn du bei `Period`/`Range`-Feldern eine - **`sa`/`eb`** bewusst einsetzen, wenn du bei `Period`/`Range`-Feldern eine
*vollständige* Trennung brauchst (siehe Abschnitt 3) z. B. „Encounter *vollständige* Trennung brauchst (siehe [Abschnitt 3](#3-matching-gegen-period-und-range))
vollständig nach Entlassung X". Für einen simplen „ab Datum X"-Filter ist z. B. „Encounter vollständig nach Entlassung X". Für einen simplen
meist `ge`/`gt` gemeint, nicht `sa`. „ab Datum X"-Filter ist meist `ge`/`gt` gemeint, nicht `sa`.
- Bei `Period`-Feldern mit möglichen offenen Enden (siehe
[Abschnitt 4](#4-offene-unvollständige-periods)) nicht vergessen: `sa`/`eb`
greifen dort strukturell nie — ggf. zusätzlich `:missing` oder Status
filtern.
- Vor dem Absetzen einer Multi-Parameter-Query lohnt sich ein kurzer Check auf - Vor dem Absetzen einer Multi-Parameter-Query lohnt sich ein kurzer Check auf
logische Konsistenz zwischen Unter- und Obergrenze, um leere Ergebnisse logische Konsistenz zwischen Unter- und Obergrenze, um leere Ergebnisse
durch Konfigurationsfehler in der eigenen Pipeline zu vermeiden. durch Konfigurationsfehler in der eigenen Pipeline zu vermeiden.
Mit diesen fünf Grafiken im Hinterkopf ohne Präfix, alle neun Präfixe Mit der Kurzreferenz oben und den sechs Grafiken im Hinterkopf ohne Präfix,
einzeln, typische Kombinationen, die volle 3×3-Matrix und die Sonderfälle alle neun Präfixe einzeln, Containment vs. Overlap bei Period/Range (offen
und dem Wissen um den Unterschied zwischen Containment und Overlap bei wie geschlossen), typische Kombinationen, die volle 3×3-Matrix und die
`Period`/`Range`-Feldern sollte die nächste `date`-Query im Sonderfälle sollte die nächste `date`-Query im FHIR-Suchparameter kein
FHIR-Suchparameter kein Rätsel mehr sein. Rätsel mehr sein.