FHIR クエリ フォールディング パターン
この記事では、FHIR 内で効果的なクエリ フォールディングを可能にするための Power Query パターンについて説明します。 ここでは、お客様が FHIR 用の Power Query コネクタを使い慣れていて、FHIR での Power Query フォールディングの基本的な目的と原則を理解していることを前提としています。
このドキュメントの使用方法
このドキュメントで示す例の一覧は完全なものではなく、クエリがフォールディングされるすべての検索パラメーターを網羅しているわけではありません。 ただし、お客様が目にすると考えられるクエリとパラメーターの種類については例を示します。 フィルター クエリ式を作成する場合は、フィルター処理を行うパラメーターを次のどれにするかを検討してください。
- プリミティブ型 (
Patient.birthDate
など)。 - 複合型。これは Power Query でレコードになります (
Patient.meta
など)。 - プリミティブ型の配列。これは Power Query でリストになります (
Patient.meta.profile
など)。 - 複合型の配列。これは Power Query でテーブルになります (多数の列を含む
Observation.code.coding
など)。
次に、以下の例の一覧を参照してください。 また、このような種類のフィルター処理パターンを、入れ子になった複数レベルのフィルター ステートメント内で組み合わせる例も示しています。 最後に、この記事では、複合検索パラメーターにフォールディングされる、より複雑なフィルター式について説明します。
各例では、フィルター式 (Table.SelectRows
) と、各フィルター ステートメントのすぐ上に、式がどのような検索パラメーターと値にフォールディングされるかを説明するコメント // Fold: ...
があります。
プリミティブ型に対するフィルター処理
ルート プロパティはリソースのルートに置かれ、通常はプリミティブ型 (文字列や日付など) ですが、コーディング フィールドとすることもできます (例: Encoding.class
)。 このセクションでは、さまざまな種類のプリミティブ ルート レベル プロパティを検索する例を示します。
生年月日で患者をフィルター処理する:
let
Patients = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Patient" ]}[Data],
// Fold: "birthdate=lt1980-01-01"
FilteredPatients = Table.SelectRows(Patients, each [birthDate] < #date(1980, 1, 1))
in
FilteredPatients
and
を使用して、1970 年代のみの期間の生年月日で患者をフィルター処理する:
let
Patients = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Patient" ]}[Data],
// Fold: "birthdate=ge1970-01-01&birthdate=lt1980-01-01"
FilteredPatients = Table.SelectRows(Patients, each [birthDate] < #date(1980, 1, 1) and [birthDate] >= #date(1970, 1, 1))
in
FilteredPatients
or
を使用して、1970 年代以外の生年月日で患者をフィルター処理する:
let
Patients = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Patient" ]}[Data],
// Fold: "birthdate=ge1980-01-01,lt1970-01-01"
FilteredPatients = Table.SelectRows(Patients, each [birthDate] >= #date(1980, 1, 1) or [birthDate] < #date(1970, 1, 1))
in
FilteredPatients
アクティブな患者の代替検索:
let
Patients = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Patient" ]}[Data],
// Fold: "active=true"
FilteredPatients = Table.SelectRows(Patients, each [active])
in
FilteredPatients
アクティブではない患者 (参照不可なものを含む可能性がある) の代替検索:
let
Patients = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Patient" ]}[Data],
// Fold: "active:not=true"
FilteredPatients = Table.SelectRows(Patients, each [active] <> true)
in
FilteredPatients
男性の患者のみを保持するためのフィルター処理:
let
Patients = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Patient" ]}[Data],
// Fold: "gender=male"
FilteredPatients = Table.SelectRows(Patients, each [gender] = "male")
in
FilteredPatients
男性ではない患者のみを保持するためのフィルター処理 (その他を含む):
let
Patients = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Patient" ]}[Data],
// Fold: "gender:not=male"
FilteredPatients = Table.SelectRows(Patients, each [gender] <> "male")
in
FilteredPatients
状態 final (コード) を使用した Observations のフィルター処理:
let
Observations = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Observation" ]}[Data],
// Fold: "status=final"
FilteredObservations = Table.SelectRows(Observations, each [status] = "final")
in
FilteredObservations
複合型に対するフィルター処理
最終更新日時に対するフィルター処理:
let
Patients = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Patient" ]}[Data],
// Fold: "_lastUpdated=2010-12-31T11:56:02.000+00:00"
FilteredPatients = Table.SelectRows(Patients, each [meta][lastUpdated] = #datetimezone(2010, 12, 31, 11, 56, 2, 0, 0))
in
FilteredPatients
class system および code (コーディング) に基づく Encounter のフィルター処理:
let
Encounters = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Encounter" ]}[Data],
// Fold: "class=s|c"
FilteredEncounters = Table.SelectRows(Encounters, each [class][system] = "s" and [class][code] = "c")
in
FilteredEncounters
code (コーディング) に基づく Encounter のフィルター処理:
let
Encounters = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Encounter" ]}[Data],
// Fold: "class=c"
FilteredEncounters = Table.SelectRows(Encounters, each [class][code] = "c")
in
FilteredEncounters
class system のみ (コーディング) に基づく Encounter のフィルター処理:
let
Encounters = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Encounter" ]}[Data],
// Fold: "class=s|"
FilteredEncounters = Table.SelectRows(Encounters, each [class][system] = "s")
in
FilteredEncounters
Observation.subject.reference
(参照) に基づく Observations のフィルター処理:
let
Observations = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Observation" ]}[Data],
// Fold: "subject=Patient/1234"
FilteredObservations = Table.SelectRows(Observations, each [subject][reference] = "Patient/1234")
in
FilteredObservations
Observation.subject.reference
(参照) でのバリエーションに基づく Observations のフィルター処理:
let
Observations = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Observation" ]}[Data],
// Fold: "subject=1234,Patient/1234,https://myfhirservice/Patient/1234"
FilteredObservations = Table.SelectRows(Observations, each [subject][reference] = "1234" or [subject][reference] = "Patient/1234" or [subject][reference] = "https://myfhirservice/Patient/1234")
in
FilteredObservations
同じ value (数量)、に基づく Quantity のフィルター処理:
let
ChargeItems = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "ChargeItem" ]}[Data],
// Fold: "quantity=1"
FilteredChargeItems = Table.SelectRows(ChargeItems, each [quantity][value] = 1)
in
FilteredChargeItems
value (数量) より大きい、に基づく Quantity のフィルター処理:
let
ChargeItems = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "ChargeItem" ]}[Data],
// Fold: "quantity=gt1.001"
FilteredChargeItems = Table.SelectRows(ChargeItems, each [quantity][value] > 1.001)
in
FilteredChargeItems
value system および code (数量) を使用した Quantity のフィルター処理:
let
ChargeItems = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "ChargeItem" ]}[Data],
// Fold: "quantity=lt1.001|s|c"
FilteredChargeItems = Table.SelectRows(ChargeItems, each [quantity][value] < 1.001 and [quantity][system] = "s" and [quantity][code] = "c")
in
FilteredChargeItems
(期間) 以降の開始に基づく、period のフィルター処理:
let
Consents = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Consent" ]}[Data],
// Fold: "period=sa2010-01-01T00:00:00.000+00:00"
FiltertedConsents = Table.SelectRows(Consents, each [provision][period][start] > #datetimezone(2010, 1, 1, 0, 0, 0, 0, 0))
in
FiltertedConsents
(期間) 以前の終了に基づく、period のフィルター処理:
let
Consents = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Consent" ]}[Data],
// Fold: "period=eb2010-01-01T00:00:00.000+00:00"
FiltertedConsents = Table.SelectRows(Consents, each [provision][period][end] < #datetimezone(2010, 1, 1, 0, 0, 0, 0, 0))
in
FiltertedConsents
複合型のテキスト フィールドのフィルター処理:
let
Observations = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Observation" ]}[Data],
// Fold: "code:text=t"
FilteredObservations = Table.SelectRows(Observations, each [code][text] = "t")
in
FilteredObservations
テキスト フィールドのフィルター処理 (次の値で始まる):
let
Observations = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Observation" ]}[Data],
// Fold: "code:text=t"
FilteredObservations = Table.SelectRows(Observations, each Text.StartsWith([code][text], "t"))
in
FilteredObservations
リストのプロパティに対するフィルター処理
profile に基づく Patients のフィルター処理:
let
Patients = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Patient" ]}[Data],
// Fold: "_profile=http://myprofile"
FilteredPatients = Table.SelectRows(Patients, each List.MatchesAny([meta][profile], each _ = "http://myprofile"))
in
FilteredPatients
カテゴリに基づく AllergyIntolerance のフィルター処理:
let
AllergyIntolerances = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "AllergyIntolerance" ]}[Data],
// Fold: "category=food"
FilteredAllergyIntolerances = Table.SelectRows(AllergyIntolerances, each List.MatchesAny([category], each _ = "food"))
in
FilteredAllergyIntolerances
欠落カテゴリに基づく AllergyIntolerance のフィルター処理:
let
AllergyIntolerances = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "AllergyIntolerance" ]}[Data],
// Fold: "category:missing=true"
FilteredAllergyIntolerances = Table.SelectRows(AllergyIntolerances, each List.MatchesAll([category], each _ = null))
in
FilteredAllergyIntolerances
よりシンプルな形式の欠落カテゴリに基づく AllergyIntolerance のフィルター処理:
let
AllergyIntolerances = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "AllergyIntolerance" ]}[Data],
// Fold: "category:missing=true"
FilteredAllergyIntolerances = Table.SelectRows(AllergyIntolerances, each [category] = null)
in
FilteredAllergyIntolerances
テーブルのプロパティに対するフィルター処理
正確な姓に基づく患者のフィルター処理:
let
Patients = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Patient" ]}[Data],
// Fold: "family:exact=Johnson"
FilteredPatients = Table.SelectRows(Patients, each Table.MatchesAnyRows([name], each [family] = "Johnson"))
in
FilteredPatients
次の値で始まる姓に基づいた Patients のフィルター処理:
let
Patients = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Patient" ]}[Data],
// Fold: "family=John"
FilteredPatients = Table.SelectRows(Patients, each Table.MatchesAnyRows([name], each Text.StartsWith([family], "John")))
in
FilteredPatients
John
または Paul
で始まる姓に基づいた Patients のフィルター処理:
let
Patients = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Patient" ]}[Data],
// Fold: "family=John,Paul"
FilteredPatients = Table.SelectRows(Patients, each Table.MatchesAnyRows([name], each Text.StartsWith([family], "John") or Text.StartsWith([family], "Paul")))
in
FilteredPatients
John
で始まる姓と、Paul
で始まる名に基づいた Patients のフィルター処理:
let
Patients = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Patient" ]}[Data],
// Fold: "family=John&given=Paul"
FilteredPatients = Table.SelectRows(
Patients,
each
Table.MatchesAnyRows([name], each Text.StartsWith([family], "John")) and
Table.MatchesAnyRows([name], each List.MatchesAny([given], each Text.StartsWith(_, "Paul"))))
in
FilteredPatients
Goal の期限日に対するフィルター処理:
let
Goals = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Goal" ]}[Data],
// Fold: "target-date=gt2020-03-01"
FilteredGoals = Table.SelectRows(Goals, each Table.MatchesAnyRows([target], each [due][date] > #date(2020,3,1)))
in
FilteredGoals
識別子に基づく患者のフィルター処理:
let
Patients = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Patient" ]}[Data],
// Fold: "identifier=s|v"
FilteredPatients = Table.SelectRows(Patients, each Table.MatchesAnyRows([identifier], each [system] = "s" and _[value] = "v"))
in
FilteredPatients
Observation コード (CodeableConcept) に対するフィルター処理:
let
Observations = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Observation" ]}[Data],
// Fold: "code=s|c"
FilteredObservations = Table.SelectRows(Observations, each Table.MatchesAnyRows([code][coding], each [system] = "s" and [code] = "c"))
in
FilteredObservations
Observation のコードとテキスト (CodeableConcept) に対するフィルター処理 (CodeableConcept):
let
Observations = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Observation" ]}[Data],
// Fold: "code:text=t&code=s|c"
FilteredObservations = Table.SelectRows(Observations, each Table.MatchesAnyRows([code][coding], each [system] = "s" and [code] = "c") and [code][text] = "t")
in
FilteredObservations
入れ子になった複数レベルのプロパティのフィルター処理
John
で始まる姓と、Paul
で始まる名に基づいた Patients のフィルター処理:
let
Patients = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Patient" ]}[Data],
// Fold: "family=John&given=Paul"
FilteredPatients =
Table.SelectRows(
Patients,
each
Table.MatchesAnyRows([name], each Text.StartsWith([family], "John")) and
Table.MatchesAnyRows([name], each List.MatchesAny([given], each Text.StartsWith(_, "Paul"))))
in
FilteredPatients
Observations からのバイタル サインのみをフィルター処理する:
let
Observations = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Observation" ]}[Data],
// Fold: "category=vital-signs"
FilteredObservations = Table.SelectRows(Observations, each Table.MatchesAnyRows([category], each Table.MatchesAnyRows([coding], each [code] = "vital-signs")))
in
FilteredObservations
system と code を使用したカテゴリ coding に基づいて Observations をフィルター処理する:
let
Observations = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Observation" ]}[Data],
// Fold: "category=s|c"
FilteredObservations = Table.SelectRows(Observations, each Table.MatchesAnyRows([category], each Table.MatchesAnyRows([coding], each [system] = "s" and [code] = "c")))
in
FilteredObservations
複数のカテゴリ (OR) に基づいて Observations をフィルター処理する:
let
Observations = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Observation" ]}[Data],
// Fold: "category=s1|c1,s2|c2"
FilteredObservations =
Table.SelectRows(
Observations,
each
Table.MatchesAnyRows(
[category],
each
Table.MatchesAnyRows(
[coding],
each
([system] = "s1" and [code] = "c1") or
([system] = "s2" and [code] = "c2"))))
in
FilteredObservations
テーブル内の入れ子になったリストのフィルター処理:
let
AuditEvents = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "AuditEvent" ]}[Data],
// Fold: "policy=http://mypolicy"
FilteredAuditEvents = Table.SelectRows(AuditEvents, each Table.MatchesAnyRows([agent], each List.MatchesAny([policy], each _ = "http://mypolicy")))
in
FilteredAuditEvents
複合検索パラメーターを使用したフィルター処理
FHIR には複合検索パラメーターが用意されています。これを使用すると、リソース内またはリソースのルートにある複合型に基づいて複数のフィールドを同時にフィルター処理することができます。 たとえば、特定のコード および 特定の値 (code-value-quantity
検索パラメーター) を使用して Observations を検索できます。 FHIR 用の Power Query コネクタでは、このような複合検索パラメーターにマップされたフィルター式の認識を試みます。 このセクションでは、これらのパターンの例をいくつか示します。 FHIR データの分析の状況では、特に Observation
リソースに対する複合検索パラメーターが重要です。
code および value quantity (身長が 150 を超える) に基づいた Observations のフィルター処理:
let
Observations = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Observation" ]}[Data],
// Fold: "code-value-quantity=http://loinc.org|8302-2$gt150"
FilteredObservations = Table.SelectRows(Observations, each Table.MatchesAnyRows([code][coding], each [system] = "http://loinc.org" and [code] = "8302-2") and [value][Quantity][value] > 150)
in
FilteredObservations
component code および value quantity (最高血圧が 140 を超える) に基づいた Observations のフィルター処理:
let
Observations = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Observation" ]}[Data],
// Fold: "component-code-value-quantity=http://loinc.org|8480-6$gt140"
FilteredObservations = Table.SelectRows(Observations, each Table.MatchesAnyRows([component], each Table.MatchesAnyRows([code][coding], each [system] = "http://loinc.org" and [code] = "8480-6") and [value][Quantity][value] > 140))
in
FilteredObservations
複数の component code value quantity (AND) (最低血圧が 90 より高く、かつ 最高血圧が 140 を超える) に基づくフィルター処理:
let
Observations = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Observation" ]}[Data],
// Fold: "component-code-value-quantity=http://loinc.org|8462-4$gt90&component-code-value-quantity=http://loinc.org|8480-6$gt140"
FilteredObservations =
Table.SelectRows(
Observations,
each
Table.MatchesAnyRows(
[component],
each
Table.MatchesAnyRows([code][coding], each [system] = "http://loinc.org" and [code] = "8462-4") and [value][Quantity][value] > 90) and
Table.MatchesAnyRows([component], each Table.MatchesAnyRows([code][coding], each [system] = "http://loinc.org" and [code] = "8480-6") and [value][Quantity][value] > 140))
in
FilteredObservations
複数の component code value quantity (OR) (最低血圧が 90 より高いか、または 最高血圧が 140 を超える) に基づくフィルター処理:
let
Observations = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Observation" ]}[Data],
// Fold: "component-code-value-quantity=http://loinc.org|8462-4$gt90,http://loinc.org|8480-6$gt140"
FilteredObservations =
Table.SelectRows(
Observations,
each
Table.MatchesAnyRows(
[component],
each
(Table.MatchesAnyRows([code][coding], each [system] = "http://loinc.org" and [code] = "8462-4") and [value][Quantity][value] > 90) or
Table.MatchesAnyRows([code][coding], each [system] = "http://loinc.org" and [code] = "8480-6") and [value][Quantity][value] > 140 ))
in
FilteredObservations
リソースのルート上、またはコンポーネント配列内にある複数の code value quantity に基づいた Observations のフィルター処理:
let
Observations = Fhir.Contents("https://myfhirserver.azurehealthcareapis.com", null){[Name = "Observation" ]}[Data],
// Fold: "combo-code-value-quantity=http://loinc.org|8302-2$gt150"
FilteredObservations =
Table.SelectRows(
Observations,
each
(Table.MatchesAnyRows([code][coding], each [system] = "http://loinc.org" and [code] = "8302-2") and [value][Quantity][value] > 150) or
(Table.MatchesAnyRows([component], each Table.MatchesAnyRows([code][coding], each [system] = "http://loinc.org" and [code] = "8302-2") and [value][Quantity][value] > 150)))
in
FilteredObservations
まとめ
クエリ フォールディングにより、Power Query フィルター式は FHIR 検索パラメーターに変換されます。 FHIR 用の Power Query コネクタでは、特定のパターンを認識し、一致する検索パラメーターの識別を試みます。 これらのパターンの認識は、より効率的な Power Query 式を記述する上で役立ちます。
次のステップ
この記事では、FHIR 検索パラメーターにフォールディングされるいくつかの種類のフィルター式について説明しました。 次は、FHIR リソース間のリレーションシップの確立に関するページを参照してください。