Update howto-fhir-date-parameter.md
This commit is contained in:
@@ -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:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -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.
|
||||||
Reference in New Issue
Block a user