Skip to main content

FHIR データの操作

FHIR サーバ・アーキテクチャでは、HL7® FHIR® データはダイナミック・オブジェクトとして表されるため、データを操作するには、ダイナミック・オブジェクトの操作方法に関する知識と、FHIR リソースを JSON で表す方法に関する知識とを組み合わせて使用します。FHIR リソースの JSON 表現の詳細は、FHIR 仕様Opens in a new tabを参照してください。

FHIR ペイロードが JSON 形式である場合、相互運用要求や応答などでは、%FromJSON メソッドを使用してペイロードをダイナミック・オブジェクトに変換し、操作できるようにします。

FHIR データとダイナミック・オブジェクト

FHIR データはインターシステムズ製品内でダイナミック・オブジェクトとして表されることがよくあるため、ダイナミック・オブジェクトの操作方法に関する知識は必須です。以下のコードは、FHIR データを含むダイナミック・オブジェクトを操作する方法を示しています。ご覧のように、FHIR リソースの JSON 表現内のフィールドの構造を把握できる程度に、FHIR 仕様Opens in a new tabに精通している必要があります。ダイナミック・オブジェクトの処理方法の詳細は、"JSON の使用" を参照してください。

これらのコード・サンプルでは、FHIR Patient リソースを含むダイナミック・オブジェクトである変数 patient が存在することを前提としています。

値の検索

以下のコードでは、2 つの異なるアプローチを使用して、Patient リソースの識別子を検索し、特定のシステムを見つけます。このコードを記述するためには、FHIR 仕様に十分精通し、Patient リソースの JSON 構造に system の名前/値ペアを持つ identifier が含まれることを把握しておく必要があります。

 // Put JSON representation of Patient resource into a dynamic object
 set patient = ##class(%DynamicObject).%FromJSONFile("c:\localdata\myPatient.json")

 //Searching for a identifier with a specific system
 set mySystem = "urn:oid:1.2.36.146.595.217.0.1"

 //Approach 1: Use an Iterator
 if $isobject(patient.identifier) 
 {
   set identifierIterator = patient.identifier.%GetIterator()
   while identifierIterator.%GetNext(, .identifier) 
   {
     if identifier.system = mySystem 
     {
       write "Found identifier: " _ identifier.value,!
     }
   }
 }

 //Approach 2: Use a 'for' loop
 if $isobject(patient.identifier) 
 {
   for i=0:1:patient.identifier.%Size()-1 
   {
     set identifier = patient.identifier.%Get(i)
     if identifier.system = mySystem 
     {
       write "Found identifier: " _ identifier.value,!
     }
   }
 }
値の抽出

以下のコードの断片は Patient リソースから姓を抽出します。

 if $isobject(patient.name) && (patient.name.%Size() > 0) 
 {
   set myFamilyname = patient.name.%Get(0).family
 }
値の変更

以下のコードの断片は Patient リソースの active フィールド (ブーリアン値) を 0 に設定します。

 do patient.%Set("active", 0, "boolean")
新規 JSON オブジェクトの追加

新規 JSON オブジェクトを既存のダイナミック・オブジェクトに追加する場合は、ObjectScript 構文または JSON 構文のどちらを使用するのかを選択できます。例えば、以下のコードは、同じ結果をもたらす 2 つの異なるアプローチを使用して、新しい identifier を患者に追加します。

 set mySystem = "urn:oid:1.2.36.146.595.217.0.1"
 set myValue = "ABCDE"

 // Approach 1: Use JSON syntax
 if '$isobject(patient.identifier) {
   set patient.identifier = ##class(%DynamicArray).%New()
  }

 do patient.identifier.%Push({
   "type": {
     "coding": [
       {
         "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
         "code": "MR"
       }
     ]
   },
   "system": (mySystem),
   "value": (myValue)
 })

 //Approach 2: Use ObjectScript syntax
 set identifier = ##class(%DynamicObject).%New()

 set typeCode = ##class(%DynamicObject).%New()
 set typeCode.system = "http://terminology.hl7.org/CodeSystem/v2-0203"
 set typeCode.code = "MR"

 set identifier.type = ##class(%DynamicObject).%New()
 set identifier.type.coding = ##class(%DynamicArray).%New()
 do identifier.type.coding.%Push(typeCode)
 set identifier.system = mySystem
 set identifier.value = myValue

 if '$isobject(patient.identifier) 
  {
   set patient.identifier = ##class(%DynamicArray).%New()
  }
  do patient.identifier.%Push(identifier)

FHIR オブジェクト・クラス

FHIR 標準は、多数の要素、構造、データ制約により非常に多くのリソース・タイプを定義します。すべてのリソース・タイプの正確な構文詳細を覚えるのは大変であり、フィールド名のスペル・ミスなどの単純なことがエラーや失敗につながることもあります。FHIR ペイロードは通常、%DynamicAbstractObjectOpens in a new tab (DAO) 構造に配置されており、InterSystems IRIS for Health エコシステム内の自動完了ツールからは見えません。

InterSystems IRIS for Health は、HSLIB に含まれる FHIR R4 オブジェクト・クラスのセットを提供します。これにより、IDE は FHIR リソースの自動完了プロンプトを提供できるようになり、認知的負荷が呼び出しから参照に移行します。要素名の綴りを覚えておく必要はありません。IDE が思い出させてくれます。

FHIR オブジェクト・モデルの IDE の自動補完を表す図。

FHIR オブジェクト・クラスの機能

各 R4 リソースには、HS.FHIRModel.R4 パッケージ内に対応する ObjectScript クラスがあります。例えば、HS.FHIRModel.R4.AllergyIntoleranceOpens in a new tab クラスは AllergyIntolerance リソースに対応します。これらのクラスは、基本仕様で定義された、リソースおよび構成要素のデータ構造とメソッドの予測可能な共有フレームワークを提供することで、開発を合理化します。

FHIRModel フレームワーク内では以下のようになります。

  • リソースに固有の要素は、HS.FHIRModel.R4.[ResourceName]X というサブパッケージ内のクラスによってモデル化されます。例えば、HS.FHIRModel.R4.AllergyIntoleranceX.ReactionOpens in a new tab は AllergyIntolerance リソースの reaction 要素のデータ構造をモデル化します。

  • 要素のコレクションは、SeqOf[ElementClassName] というクラスによってモデル化されます。リソースに固有のコレクションの場合、このクラスは [ResourceName]X サブパッケージ内に実装されます。例えば、HS.FHIRModel.R4.AllergyIntoleranceX.SeqOfAllergyIntoleranceXReactionOpens in a new tab は AllergyIntolerance リソースの reaction 要素のコレクションをモデル化します。

    SeqOf[ElementClassName] 構造を表す図。

  • リソース・クラスには、その中の複雑な要素または要素のコレクションごとに、Include[ElementName]() メソッドが含まれます。このメソッドは、要素またはコレクションの入れ子になった適切なデータ構造をリソース・オブジェクトに追加します。

  • コレクション・クラスには、新しい要素をコレクション・オブジェクトに追加する MakeEntry() メソッドが含まれます。以下の例は、MakeEntry()Include[ElementName]() の両方を示しています。

    Set claim = ##class(HS.FHIRModel.R4.Claim).%New()
    Do claim.IncludeInsurance()
    Set ins = claim.insurance.MakeEntry()
    Do ins.includeCoverage()
    Set ins.coverage.display = "Supra Health"
    (...)
    
  • すべてのクラスは、コンテンツを取得、移動、変更するための共通のメソッドのセットを実装します。これらのメソッドは、%Library.AbstractSet クラスから継承されます。 

  • fromDao() クラス・メソッドを使用して、FHIR リソースの JSON を表す動的抽象オブジェクトを、対応する FHIRModel クラスのインスタンスに変換できます。逆に、toDao() メソッドを使用して、FHIR リソースを表す FHIRModel クラスのインスタンスを動的抽象オブジェクトに変換できます。その後、ダイナミック・オブジェクトの %ToJSON() メソッドを使用して、有効な JSON ペイロードに変換できます。FHIRModel クラスの toString() メソッドを使用して、文字列形式の JSON ペイロードを直接生成することもできます。

  • 必要に応じて、FHIR オブジェクト・クラスを拡張できます。

FHIR オブジェクトで使用するメソッド

このリストには、動的抽象オブジェクト (DAO) 構造として表される FHIR リソースと FHIR オブジェクト間で変換する際、および FHIR オブジェクトを操作する際に必要になる可能性が高いメソッドが含まれます。これらのメソッドの詳細、またはその他のメソッドについては、クラス・リファレンスの "%Library.AbstractSet" クラスまたは関連する "HS.FHIRModel.R4" サブクラスを参照してください。

考えられるワークフローは次のようなものです。

  1. FHIR リソースを JSON ペイロードとして受け取ります。

  2. "FHIR データの操作" の説明に従って、JSON ペイロードを %DynamicObjectOpens in a new tab (%DynamicAbstractObjectOpens in a new tab のサブクラス) に変換します。

  3. fromDao() を使用して、%DynamicObjectOpens in a new tab を類似する FHIRModel クラスのオブジェクトに変換します。

  4. 必要に応じて、FHIR オブジェクトを操作します。

  5. toString() を使用して、FHIR オブジェクトを JSON 形式に戻します。

FHIR オブジェクトの変換メソッド

fromDao(dao As %DynamicAbstractObject) As <HS.FHIRModel.R4 subclass>

DAO から指定された FHIR オブジェクトに変換します。例えば、JSON ペイロード dao から FHIR オブジェクト cls に変換する場合、以下のようになります。

Set rType = dao.resourceType
Set cls = $CLASSMETHOD("I4H.FhirR4."_rType,"fromDao",dao)
toDao() As %DynamicAbstractObject

FHIR オブジェクトから DAO に変換します。例えば、FHIR オブジェクト cls から DAO に変換する場合、以下のようになります。

Set newDao = cls.toDao()
toString()

FHIR オブジェクトから直接、文字列形式の JSON ペイロードに変換します。例えば、FHIR オブジェクト cls を直接 JSON ペイロード (文字列) に変換する場合、以下のようになります。

Set payload = cls.toString()

FHIR オブジェクトの取得メソッド

これらの取得メソッドの詳細な例は、"FHIR オブジェクト・モデルでの反復処理" を参照してください。

get(key As %DataType) as %Any

指定されたキー (キーと値のコレクションのラベル、または 0 から始まるシーケンスの数値内の位置) によって識別される要素を取得します。

iterator() as %Iterator

このセットのメンバに対する反復子を返します。返されるオブジェクトは、以下のメソッドを持ちます。

  • hasNext() — さらに処理を待機しているデータがある場合は true (1) を返します。

  • next() — キューにあるデータから引き出された、key および value というプロパティを持つ実際のタプルを返します。

FHIR オブジェクトの設定およびクリア操作

設定およびクリア・メソッドを呼び出すには、Do [object].[method] 構文を使用します。例えば、add() メソッドの場合、以下のようになります。

Do item.IncludeEncounter()
Set ref = item.encounter.MakeEntry()
Set ref.reference = "urn:uuid:d8c2b161-7e3e-4e7f-9adc-ae464a9608bc"
Do item.encounter.add(ref)
add(value As %Any) as %AbstractSet

シーケンスのみ。新規メンバ value をシーケンスに追加します。

addAll(values As %AbstractSet) as %AbstractSet

シーケンスのみ。シーケンス values のすべてのメンバを現在のシーケンスに追加します。

clear()

現在のセットからすべての要素を削除します。

put(key As %DataType, value As %Any) as %AbstractSet

ラベル付きセットのみ。value をセットに入れて、ラベル key に関連付けます。要素が既にラベル key に関連付けられている場合は、新しい value に置き換えます。

putAll(keys As %AbstractSet, values As %AbstractSet) as %AbstractSet)

ラベル付きセットのみ。すべての {keys[n], values[n]} 要素を、values のすべての n のセットに入れます。

remove(key As %DataType) as %Any

key によって識別されたメンバをセットから削除します。

replace(key As %DataType, value As %Any) as %AbstractSet

ラベル付きセットのみ。key によって識別された要素の値を、指定された新しい value に置き換えます。

FHIR オブジェクトのイントロスペクション操作

apply(expression As %Any) as %AbstractSet

指定された SQL-JSON パス言語 (JPL) の式に一致するメンバの配列を返します。例えば、特定の Doctor リソースに関連付けられた電子メール・アドレスを見つける場合、以下のようになります。

Set key = "system"
Set value = "email"
Set query = "$[*]?(@."_key_"=='"_value_"')"
Set email = doctor.telecom.apply(query)
contains(key As %DataType) as %Boolean

key が現在、セットまたはシーケンスの NULL 以外のメンバである場合は true (1) を返し、そうでない場合は false (0) を返します。セットにラベルが付けられている場合、key は文字列である必要があります。シーケンスを処理する場合、key はゼロ以上の数値である必要があります。

containsAll(array As %DynamicArray) as %Boolean

array にリストされているすべてのキーがセットに含まれる場合、true (1) を返します。

size() as %Integer

このセット内の NULL 以外のメンバの数を返します。

FHIR オブジェクト・モデルの実用的なヒント

以下のトピックでは、FHIR オブジェクト・モデルを最も効果的に使用するための提案と実例を提供します。

FHIR オブジェクト・モデルでの反復処理

以下のコーディング・パターンは、基盤となるデータが動的オブジェクトと静的オブジェクトのどちらにあるかに関係なく、FHIR オブジェクト・モデル内のどこにでも適用できます。

  1. iterator() メソッドを使用して、コンテナ・クラスから反復子を要求します。

  2. hasNext() メソッドを使用して、アクセスする新しいデータがある限りループします。ループ内では、以下を実行します。

    1. next() メソッドを使用して、次のキー/値またはインデックス/値のペアを取得します。

    2. 必要に応じて、.key および .value を使用してデータを処理します。

以下の例は list で開始します。これは、Bundle リソースの entry コレクションに見られるような、FHIR リソース・レコードの順序付きのコレクションです。このコレクションを反復処理し、各エントリの resourceType フィールドを調べ、見つかった各タイプのリソースの数を動的オブジェクトの summary に入力します。

Set summary = {}
Set itr = list.iterator()
While (itr.hasNext()) {
     Set rsc = itr.next().value
     Set rscName = rsc.resourceType
     Set count = summary.%Get(rscName,0)+1
     Do summary.%Set(rscName,count)
}

summary オブジェクトが DAO である、とシステムに対して明示的に指定した場合でも、同じパターンに従って結果を出力できます。この場合、単に各ノードを順番に参照するのではなく、キーと値の両方を確認します。

Write !,"BUNDLE SUMMARY:",!
Write $J("RESOURCE TYPE",35)_"   COUNT",!
Set itr = summary.iterator()
While (itr.hasNext()) {
     Set node = itr.next()
     Write $J(node.key,35)_"   "_node.value,!
}

IDE の FHIR オブジェクト・モデルの自動補完の候補の絞り込み

IDE にいくらかのヒントを提供すると、IDE は、自動補完のオプションを提示するときに、クラス、メソッド、プロパティ名に関してより有意義な候補を提供できるようになります。

#dim 指示文

IDE が有用な候補を挙げられるようにする最も簡単な方法は、#dim 指示文を使用することです。以下に例を示します。

#dim info As HS.HC.FHIRModel.R4.ClaimX.SupportingInfo

この例では、変数が Claim リソース内の SupportingInfo データ構造のインスタンスを参照することを IDE に通知して、可能性の高い一連の自動補完のオプションを大幅に絞り込みます。

%New() 指示文

%New() 指示文は、新しい最上位のリソースを割り当て、ORef に関連付けられる基本の型を IDE に通知します。以下に例を示します。

Set claim = ##class(HS.HC.FHIRModel.R4.Claim).%New()

この指示文に基づき、IDE は Claim.cls のクラス定義に基づいて、‘claim.’ が先頭に付いた任意のトークンに対して、メソッド名とプロパティ名の候補を提示できます。

ClassMethod 宣言

FHIR オブジェクト・クラスは単純に ORef の型定義であり、任意のメソッドに対してパラメータを定義するときに使用できます。これは、IDE に有意義な自動補完の候補を提供するための重要なヒントを提供します。以下に例を示します。

ClassMethod ExtractData(bundle As HS.HC.FHIRModel.R4.Bundle)

この例では、受信する ORef を Bundle リソースのインスタンスとして扱うようシステムに指示すると共に、’bundle.’ が参照されるたびに、IDE が Bundle クラスの適切な構造と機能に関して候補を提示できるようにします。

データ・ロード・ユーティリティ

データ・ロード・ユーティリティは、ローカル・システム・ディレクトリ内に格納されているリソースとバンドルを、HTTP を経由するか、または HTTP を経由せずに FHIR サーバに直接送信します。データ・ロード・ユーティリティに提供するローカル FHIR データは、個々のリソース、バンドル、またはその両方にすることができます。データは、有効なファイル拡張子 (.json.ndjson.xml) を持つ JSON、NDJSON、および XML ファイルの任意の組み合わせで提供できます。このユーティリティの一般的な使用法は、大量の合成データをオープン・ソースの患者ジェネレータから FHIR サーバに提供することです。

可能な限り高速にデータを FHIR サーバに送ることが目的である場合は、HTTP を使用せずにデータをサーバに直接送信する方が効率的です。この場合、FHIRServer 引数を、サーバのエンドポイントと共にデータ・ロード・ユーティリティに渡します。例えば、サーバのエンドポイントが /fhirapp/fhir/r4 で、FHIR バンドルが含まれるディレクトリが c:\localdata であるとします。この場合、データ・ロード・ユーティリティを実行するには、以下のように入力します。

 Set status = ##class(HS.FHIRServer.Tools.DataLoader).SubmitResourceFiles(
                      "c:\localdata",
                      "FHIRServer",
                      "/fhirapp/fhir/r4")

ファイルの処理が終了すると、"Completed Successfully" と表示されます。表示されない場合は、"Do $SYSTEM.Status.DisplayError(status)" と入力するとエラーを表示できます。

または、HTTP を、サービス・レジストリの HTTP サービスの名前と共に渡すことで、すべてのバルク・データを HTTP 上で送信することもできます。HTTP サービスの作成の詳細は、"サービス・レジストリの管理" を参照してください。例えば、以下を実行できます。

 Set status = ##class(HS.FHIRServer.Tools.DataLoader).SubmitResourceFiles(
                      "c:\localdata",
                      "HTTP",
                      "MyUniqueServiceName")

データ・ロード・ユーティリティの SubmitResourceFiles() ユーティリティはオプションの引数を取ります。進行状況を表示するかどうかを制御するオプション、統計をログに記録するオプション、ディレクトリ内の処理対象ファイルの数を制御するオプション、または変換テーブルを適用するオプションです。さらに、ファイルをマルチスレッド・オペレーションとして処理するワーカの数を指定するオプションもあります。これらの引数の詳細は、"HS.FHIRServer.Tools.DataLoader.SubmitResourceFiles()Opens in a new tab" を参照してください。

このユーティリティは、FHIR データを非同期でロードする API も提供します。この API でメソッドを使用し、Job()Opens in a new tab を使用して新しいデータ・ロード操作を開始できます。Job()Opens in a new tab メソッドは、参照によってこの操作のジョブ ID を返します。その後、返されたジョブ ID を使用してステータスを確認し (Status()Opens in a new tab を使用)、取り消し (Cancel()Opens in a new tab を使用)、完了後に関連するグローバルをクリーンアップ (CleanUp()Opens in a new tab を使用) できます。

管理ポータルを使用したバンドルのロード

Note:

このオプションは、プロダクション以外の FHIR サーバでのみ利用できます。

また、以下のように管理ポータルで便利な [バンドルのロード] メニュー・オプションを使用して、カスタムのバンドルをロードすることもできます。

  1. 管理ポータルで、[ホーム][Health]→[[MyFHIRNamespace]]→[FHIR サーバ管理] に移動します。

  2. 関連する FHIR サーバのタイルで、メニューを開き [バンドルのロード] を選択します。

  3. 表示されるダイアログで、以下のようにカスタムの FHIR バンドルをロードできます。

    カスタムの FHIR バンドル

    クライアントがサーバにファイルをアップロードできるようにし、その後 HTTP を経由せずに FHIR リソースを FHIR サーバに直接送信します。

    1. [カスタムの FHIR バンドル] のラジオ・ボタンを選択し、[次へ] をクリックします。

    2. [カスタム・バンドルの選択] をクリックし、目的のバンドルを参照します。

    3. [読み込み] をクリックします。

データのロードの詳細や、データ・ロード・ユーティリティを使用してバンドルとリソースをロードする手順については、"データ・ロード・ユーティリティ" を参照してください。

FeedbackOpens in a new tab