FHIR リソースの検索

このページでは、FHIR ストアで FHIR リソースを検索する方法の基本的な手順について説明します。FHIR リソースを検索することは、FHIR データをクエリして分析情報を得るための主要な方法です。

Cloud Healthcare API で FHIR リソースを検索するには、次の方法があります。

  • Google Cloud コンソールでの FHIR ビューアの使用。
  • projects.locations.datasets.fhirStores.fhir.search メソッドの使用。このメソッドでは、FHIR リソースを次のような方法で検索できます。
    • GET リクエスト
    • POST リクエスト

このページでは、頻繁に使用される検索機能の多くについて概要を説明しますが、Cloud Healthcare API でサポートされている FHIR 検索仕様のすべての部分を示しているわけではありません。

FHIR ビューアの使用

FHIR ビューアは、Google Cloud コンソールに存在するページであり、FHIR リソースの内容を検索して表示できます。

FHIR ストア内のリソースを検索するには、次の手順を行います。

  1. Google Cloud コンソールで、[FHIR ビューア] ページに移動します。

    FHIR ビューアに移動

  2. [FHIR ストア] プルダウン リストでデータセットを選択し、データセット内の FHIR ストアを選択します。

  3. リソースタイプのリストをフィルタするには、表示するリソースタイプを検索します。

    1. [リソースタイプ] フィールドをクリックします。

    2. 表示される [プロパティ] プルダウン リストで、[リソースタイプ] を選択します。

    3. リソースタイプを入力します。

    4. 別のリソースタイプを検索するには、表示される [演算子] プルダウン リストから [OR] を選択し、別のリソースタイプを入力します。

  4. リソースタイプの一覧で、検索するリソースタイプを選択します。

  5. 表示されるリソースの表の検索ボックスに、検索する値を入力します。

FHIR ビューアが、検索結果をテーブルに表示します。リソースを選択すると、FHIR ビューアにそのリソースの内容が表示されます。

リソースの内容を表示すると、そのリソース内のデータを検索できます。

リソース内のデータを検索する手順は、次のとおりです。

  1. リソースを選択します。

  2. [FHIR ビューア] ペインで [要素] タブをクリックします。

  3. 検索ボックスに検索したい値を入力します。

FHIR リソース内のバイナリデータのダウンロード

FHIR ビューアでリソースに関連付けられている利用可能なバイナリデータをダウンロードする手順は次のとおりです。

  1. リソースを選択してください。

  2. [FHIR ビューア] ペインで [要素] タブをクリックします。

  3. 必要に応じて要素を開き、必要なリソース要素にアクセスします。

  4. [ファイルをダウンロード] をクリックして、使用可能なデータをダウンロードします。

高度な検索クエリの作成と実行

高度な検索クエリでは、FHIR 検索の仕様を利用して特定の FHIR リソースを検索できます。

高度な検索クエリを作成するには、次の手順を行います。

  1. [FHIR ビューア] ページで、[検索] タブをクリックします。

  2. 検索クエリを作成するには、[クエリビルダーを開く] をクリックします。

    [クエリ選択] パネルが表示されます。

  3. [FHIR リソースタイプの選択] リストから、検索する FHIR リソースタイプを選択します。

  4. [続行] をクリックします。

  5. [パラメータ] リストから、リソースの検索に使用するパラメータを選択します。

  6. [修飾子] リストから、クエリに適用する修飾子を選択します。リストには、選択したパラメータのデータ型と互換性のある修飾子のみが含まれます。

    これは省略可能な選択項目です。修飾子が選択されていない場合は、等価性チェックが実行されます。

  7. [] にクエリ パラメータの値を入力します。

  8. 複数のパラメータ値を追加するには、[OR] をクリックします。これにより、検索クエリにリソース パラメータの複数の値を含めることができます。

    検索クエリを作成すると、[クエリのプレビュー] ペインにクエリが表示されます。検索クエリの URL 全体を表示するには、[フルパスを表示] をクリックします。

  9. 複数のパラメータを追加するには、[AND] をクリックします。

  10. [続行] をクリックします。

  11. 検索クエリで返されるリソースによって参照されるリソースを含めるには、[ncluded parameters] プルダウン リストからリソース パラメータを選択します。

  12. 検索クエリで返されるリソースを参照するリソースを含めるには、[反対方向の含まれるパラメータ] プルダウン リストからリソース パラメータを選択します。

  13. [Done] をクリックして検索クエリを保存します。

    保存した検索クエリは、[FHIR 検索オペレーション] フィールドに表示されます。

  14. クエリでリソースを検索するには、[検索を実行] をクリックします。

    検索結果は [検索結果] リストに表示されます。検索で返されたリソースの詳細を表示するには、リスト内のリソースをクリックします。

  15. クエリをクエリ テンプレートとして保存するには、[テンプレートを保存] をクリックし、[テンプレートを保存] または [テンプレートに名前を付けて保存] を選択します。クエリの名前と説明を入力するように求められます。クエリ パラメータはテンプレートに保存されますが、定義された値は削除されます。

検索クエリの例

次の例は、特定の医療機関、Practitioner/12345 から 2021 年 8 月の Claim リソースを検索する検索クエリを示しています。

  • パラメータ: care-team
    • : Practitioner/12345
  • 演算子: AND
  • パラメータ: created
    • 接頭辞: lt (lesser than)
    • : 8/1/21, 12:00 AM
  • 演算子: AND
  • パラメータ: created
    • 接頭辞: gt (greater than)
    • : 8/31/21, 11:59 PM

[Query Selection] パネルで次のように構成し、[Query Preview] ペインでクエリをプレビューします。クエリが [FHIR 検索オペレーション] フィールドに表示されます。

FHIR の高度な検索クエリ

検索クエリの編集

検索クエリを編集するには、次のいずれかを行います。

  • クエリビルダーでクエリを編集するには、[Open Query Builder] をクリックします。
  • クエリを手動で編集するには、テキスト ボックスでパラメータ値を編集します。

クエリ テンプレートの実行

保存したテンプレートからクエリを実行するには、次の手順を行います。

  1. [Saved templates] をクリックします。

    [Query Selection] パネルの [Search templates] タブが表示され、保存されているすべてのクエリ テンプレートが表示されます。

  2. 実行するクエリ テンプレートを選択して、[Done] をクリックします。

    テンプレートの検索クエリが、[FHIR search operation] フィールドに値が表示されます。

  3. 検索クエリの値を定義するには、フィールドでパラメータ値を編集します。

  4. [検索を実行] をクリックして、クエリでリソースを検索します。

search メソッドの使用

REST API で FHIR リソースを検索するには、projects.locations.datasets.fhirStores.fhir.search メソッドを使用します。このメソッドを呼び出すには、GET リクエストまたは POST リクエストを使用します。

GETsearch メソッドを使用する

次のサンプルは、GETprojects.locations.datasets.fhirStores.fhir.search メソッドを使用して、特定の FHIR ストア内のリソースを検索する方法を示しています。

curl

FHIR ストア内のリソースを検索するには、GET リクエストを行い、次の情報を指定します。

  • データセットの名前
  • FHIR ストアの名前
  • 検索するリソースのタイプ
  • 検索する情報が含まれるクエリ文字列。検索クエリの作成をご覧ください。
  • アクセス トークン

次のサンプルは、curl を使用して姓が「Smith」のすべての患者を検索する GET リクエストを示しています。

curl -X GET \
     -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
     "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient?family:exact=Smith"

リクエストが成功すると、サーバーはレスポンスを JSON 形式の FHIR Bundle として返します。Bundle.typesearchset で、検索結果は Bundle.entry 配列のエントリです。この例では、リクエストはそのリソース内のデータを含む単一の患者リソースを返します。

{
  "entry": [
    {
      "fullUrl": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/PATIENT_ID",
      "resource": {
        "birthDate": "1970-01-01",
        "gender": "female",
        "id": "PATIENT_ID",
        "meta": {
          "lastUpdated": "LAST_UPDATED",
          "versionId": "VERSION_ID"
        },
        "name": [
          {
            "family": "Smith",
            "given": [
              "Darcy"
            ],
            "use": "official"
          }
        ],
        "resourceType": "Patient"
      },
      "search": {
        "mode": "match"
      }
    }
  ],
  "link": [
    {
      "url": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/?family%3Aexact=Smith"
    }
  ],
  "resourceType": "Bundle",
  "total": 1,
  "type": "searchset"
}

PowerShell

FHIR ストア内のリソースを検索するには、GET リクエストを行い、次の情報を指定します。

  • データセットの名前
  • FHIR ストアの名前
  • 検索するリソースのタイプ
  • 検索する情報が含まれるクエリ文字列。検索クエリの作成をご覧ください。
  • アクセス トークン

次のサンプルは、Windows PowerShell を使用して姓が「Smith」のすべての患者を検索する GET リクエストを示しています。

$cred = gcloud auth application-default print-access-token
$headers = @{ Authorization = "Bearer $cred" }

Invoke-RestMethod `
  -Method Get `
  -Headers $headers `
  -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/RESOURCE_TYPE?family:exact=Smith" | ConvertTo-Json

リクエストが成功すると、サーバーはレスポンスを JSON 形式の FHIR Bundle として返します。Bundle.typesearchset で、検索結果は Bundle.entry 配列のエントリです。この例では、リクエストはそのリソース内のデータを含む単一の患者リソースを返します。

{
  "entry": [
    {
      "fullUrl": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/PATIENT_ID",
      "resource": {
        "birthDate": "1970-01-01",
        "gender": "female",
        "id": "PATIENT_ID",
        "meta": {
          "lastUpdated": "LAST_UPDATED",
          "versionId": "VERSION_ID"
        },
        "name": [
          {
            "family": "Smith",
            "given": [
              "Darcy"
            ],
            "use": "official"
          }
        ],
        "resourceType": "Patient"
      },
      "search": {
        "mode": "match"
      }
    }
  ],
  "link": [
    {
      "url": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/?family%3Aexact=Smith"
    }
  ],
  "resourceType": "Bundle",
  "total": 1,
  "type": "searchset"
}

Java

import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.healthcare.v1.CloudHealthcare;
import com.google.api.services.healthcare.v1.CloudHealthcareScopes;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Collections;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;

public class FhirResourceSearchGet {
  private static final String FHIR_NAME =
      "projects/%s/locations/%s/datasets/%s/fhirStores/%s/fhir/%s";
  // The endpoint URL for the Healthcare API. Required for HttpClient.
  private static final String API_ENDPOINT = "https://healthcare.googleapis.com";
  private static final JsonFactory JSON_FACTORY = new GsonFactory();
  private static final NetHttpTransport HTTP_TRANSPORT = new NetHttpTransport();

  public static void fhirResourceSearchGet(String resourceName)
      throws IOException, URISyntaxException {
    // String resourceName =
    //    String.format(
    //        FHIR_NAME, "project-id", "region-id", "dataset-id", "fhir-store-id");
    // String resourceType = "Patient";

    // Instantiate the client, which will be used to interact with the service.
    HttpClient httpClient = HttpClients.createDefault();
    String uri = String.format("%s/v1/%s", API_ENDPOINT, resourceName);
    URIBuilder uriBuilder = new URIBuilder(uri).setParameter("access_token", getAccessToken());
    // To set additional parameters for search filtering, add them to the URIBuilder. For
    // example, to search for a Patient with the family name "Smith", specify the following:
    // uriBuilder.setParameter("family:exact", "Smith");

    HttpUriRequest request =
        RequestBuilder.get()
            .setUri(uriBuilder.build())
            .build();

    // Execute the request and process the results.
    HttpResponse response = httpClient.execute(request);
    HttpEntity responseEntity = response.getEntity();
    if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
      System.err.print(
          String.format(
              "Exception searching GET FHIR resources: %s\n", response.getStatusLine().toString()));
      responseEntity.writeTo(System.err);
      throw new RuntimeException();
    }
    System.out.println("FHIR resource GET search results: ");
    responseEntity.writeTo(System.out);
  }

  private static CloudHealthcare createClient() throws IOException {
    // Use Application Default Credentials (ADC) to authenticate the requests
    // For more information see https://cloud.google.com/docs/authentication/production
    GoogleCredentials credential =
        GoogleCredentials.getApplicationDefault()
            .createScoped(Collections.singleton(CloudHealthcareScopes.CLOUD_PLATFORM));
    // Create a HttpRequestInitializer, which will provide a baseline configuration to all requests.
    HttpRequestInitializer requestInitializer =
        request -> {
          new HttpCredentialsAdapter(credential).initialize(request);
          request.setConnectTimeout(60000); // 1 minute connect timeout
          request.setReadTimeout(60000); // 1 minute read timeout
        };
    // Build the client for interacting with the service.
    return new CloudHealthcare.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer)
        .setApplicationName("your-application-name")
        .build();
  }

  private static String getAccessToken() throws IOException {
    GoogleCredentials credential =
        GoogleCredentials.getApplicationDefault()
            .createScoped(Collections.singleton(CloudHealthcareScopes.CLOUD_PLATFORM));

    return credential.refreshAccessToken().getTokenValue();
  }
}

Node.js

// Import google-auth-library for authentication.
const {GoogleAuth} = require('google-auth-library');

const searchFhirResourcesGet = async () => {
  const auth = new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/cloud-platform',
  });
  // TODO(developer): uncomment these lines before running the sample
  // const cloudRegion = 'us-central1';
  // const projectId = 'adjective-noun-123';
  // const datasetId = 'my-dataset';
  // const fhirStoreId = 'my-fhir-store';
  // const resourceType = 'Patient';
  const url = `https://healthcare.googleapis.com/v1/projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}/fhirStores/${fhirStoreId}/fhir/${resourceType}`;

  const params = {};
  // Specify search filters in a params object. For example, to filter on a
  // Patient with the last name "Smith", set resourceType to "Patient" and
  // specify the following params:
  // params = {'family:exact' : 'Smith'};
  const client = await auth.getClient();
  const response = await client.request({url, method: 'GET', params});
  const resources = response.data.entry;
  console.log(`Resources found: ${resources.length}`);
  console.log(JSON.stringify(resources, null, 2));
};

searchFhirResourcesGet();

Python

def search_resources_get(
    project_id,
    location,
    dataset_id,
    fhir_store_id,
    resource_type,
):
    """
    Uses the searchResources GET method to search for resources in the given FHIR store.

    See https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/healthcare/api-client/v1/fhir
    before running the sample."""
    # Imports Python's built-in "os" module
    import os

    # Imports the google.auth.transport.requests transport
    from google.auth.transport import requests

    # Imports a module to allow authentication using a service account
    from google.oauth2 import service_account

    # Gets credentials from the environment.
    credentials = service_account.Credentials.from_service_account_file(
        os.environ["GOOGLE_APPLICATION_CREDENTIALS"]
    )
    scoped_credentials = credentials.with_scopes(
        ["https://www.googleapis.com/auth/cloud-platform"]
    )
    # Creates a requests Session object with the credentials.
    session = requests.AuthorizedSession(scoped_credentials)

    # URL to the Cloud Healthcare API endpoint and version
    base_url = "https://healthcare.googleapis.com/v1"

    # TODO(developer): Uncomment these lines and replace with your values.
    # project_id = 'my-project'  # replace with your GCP project ID
    # location = 'us-central1'  # replace with the parent dataset's location
    # dataset_id = 'my-dataset'  # replace with the parent dataset's ID
    # fhir_store_id = 'my-fhir-store' # replace with the FHIR store ID
    # resource_type = 'Patient'  # replace with the FHIR resource type
    url = f"{base_url}/projects/{project_id}/locations/{location}"

    resource_path = "{}/datasets/{}/fhirStores/{}/fhir/{}".format(
        url, dataset_id, fhir_store_id, resource_type
    )

    response = session.get(resource_path)
    response.raise_for_status()

    resources = response.json()

    print(
        "Using GET request, found a total of {} {} resources:".format(
            resources["total"], resource_type
        )
    )
    print(json.dumps(resources, indent=2))

    return resources

POSTsearch メソッドを使用する

次のサンプルは、POSTprojects.locations.datasets.fhirStores.fhir.search メソッドを使用して、特定の FHIR ストア内のリソースを検索する方法を示しています。

curl

FHIR ストア内のリソースを検索するには、POST リクエストを行い、次の情報を指定します。

  • データセットの名前
  • FHIR ストアの名前
  • 検索するリソースのタイプ
  • 検索する情報が含まれるクエリ文字列。検索クエリの作成をご覧ください。
  • アクセス トークン

次のサンプルは、curl を使用して姓が「Smith」のすべての患者を検索する POST リクエストを示しています。

curl -X POST \
    --data "" \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/fhir+json; charset=utf-8" \
    "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/_search?family:exact=Smith"

リクエストが成功すると、サーバーはレスポンスを JSON 形式の FHIR Bundle として返します。Bundle.typesearchset で、検索結果は Bundle.entry 配列のエントリです。この例では、リクエストはそのリソース内のデータを含む単一の患者リソースを返します。

{
  "entry": [
    {
      "fullUrl": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/PATIENT_ID",
      "resource": {
        "birthDate": "1970-01-01",
        "gender": "female",
        "id": "PATIENT_ID",
        "meta": {
          "lastUpdated": "LAST_UPDATED",
          "versionId": "VERSION_ID"
        },
        "name": [
          {
            "family": "Smith",
            "given": [
              "Darcy"
            ],
            "use": "official"
          }
        ],
        "resourceType": "Patient"
      },
      "search": {
        "mode": "match"
      }
    }
  ],
  "link": [
    {
      "url": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/?family%3Aexact=Smith"
    }
  ],
  "resourceType": "Bundle",
  "total": 1,
  "type": "searchset"
}

PowerShell

FHIR ストア内のリソースを検索するには、POST リクエストを行い、次の情報を指定します。

  • データセットの名前
  • FHIR ストアの名前
  • 検索するリソースのタイプ
  • 検索する情報が含まれるクエリ文字列。検索クエリの作成をご覧ください。
  • アクセス トークン

次のサンプルは、Windows PowerShell を使用して姓が「Smith」のすべての患者を検索する POST リクエストを示しています。

$cred = gcloud auth application-default print-access-token
$headers = @{ Authorization = "Bearer $cred" }

Invoke-RestMethod `
  -Method Post `
  -Headers $headers `
  -ContentType: "application/fhir+json; charset=utf-8" `
  -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/_search?family:exact=Smith" | ConvertTo-Json

リクエストが成功すると、サーバーはレスポンスを JSON 形式の FHIR Bundle として返します。Bundle.typesearchset で、検索結果は Bundle.entry 配列のエントリです。この例では、リクエストはそのリソース内のデータを含む単一の患者リソースを返します。

{
  "entry": [
    {
      "fullUrl": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/PATIENT_ID",
      "resource": {
        "birthDate": "1970-01-01",
        "gender": "female",
        "id": "PATIENT_ID",
        "meta": {
          "lastUpdated": "LAST_UPDATED",
          "versionId": "VERSION_ID"
        },
        "name": [
          {
            "family": "Smith",
            "given": [
              "Darcy"
            ],
            "use": "official"
          }
        ],
        "resourceType": "Patient"
      },
      "search": {
        "mode": "match"
      }
    }
  ],
  "link": [
    {
      "url": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/?family%3Aexact=Smith"
    }
  ],
  "resourceType": "Bundle",
  "total": 1,
  "type": "searchset"
}

Java

import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.healthcare.v1.CloudHealthcare;
import com.google.api.services.healthcare.v1.CloudHealthcareScopes;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Collections;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;

public class FhirResourceSearchPost {
  private static final String FHIR_NAME =
      "projects/%s/locations/%s/datasets/%s/fhirStores/%s/fhir/%s";
  // The endpoint URL for the Healthcare API. Required for HttpClient.
  private static final String API_ENDPOINT = "https://healthcare.googleapis.com";
  private static final JsonFactory JSON_FACTORY = new GsonFactory();
  private static final NetHttpTransport HTTP_TRANSPORT = new NetHttpTransport();

  public static void fhirResourceSearchPost(String resourceName)
      throws IOException, URISyntaxException {
    // String resourceName =
    //    String.format(
    //        FHIR_NAME, "project-id", "region-id", "dataset-id", "store-id", "resource-type");

    // Instantiate the client, which will be used to interact with the service.
    HttpClient httpClient = HttpClients.createDefault();
    String uri = String.format("%s/v1/%s/_search", API_ENDPOINT, resourceName);
    URIBuilder uriBuilder = new URIBuilder(uri).setParameter("access_token", getAccessToken());
    // To set additional parameters for search filtering, add them to the URIBuilder. For
    // example, to search for a Patient with the family name "Smith", specify the following:
    // uriBuilder.setParameter("family:exact", "Smith");

    // Set a body otherwise HttpClient complains there is no Content-Length set.
    StringEntity requestEntity = new StringEntity("");

    HttpUriRequest request =
        RequestBuilder.post()
            .setUri(uriBuilder.build())
            .setEntity(requestEntity)
            .addHeader("Content-Type", "application/fhir+json")
            .addHeader("Accept-Charset", "utf-8")
            .addHeader("Accept", "application/fhir+json; charset=utf-8")
            .build();

    // Execute the request and process the results.
    HttpResponse response = httpClient.execute(request);
    HttpEntity responseEntity = response.getEntity();
    if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
      System.err.print(
          String.format(
              "Exception searching POST FHIR resources: %s\n",
              response.getStatusLine().toString()));
      responseEntity.writeTo(System.err);
      throw new RuntimeException();
    }
    System.out.println("FHIR resource POST search results: ");
    responseEntity.writeTo(System.out);
  }

  private static CloudHealthcare createClient() throws IOException {
    // Use Application Default Credentials (ADC) to authenticate the requests
    // For more information see https://cloud.google.com/docs/authentication/production
    GoogleCredentials credential =
        GoogleCredentials.getApplicationDefault()
            .createScoped(Collections.singleton(CloudHealthcareScopes.CLOUD_PLATFORM));

    // Create a HttpRequestInitializer, which will provide a baseline configuration to all requests.
    HttpRequestInitializer requestInitializer =
        request -> {
          new HttpCredentialsAdapter(credential).initialize(request);
          request.setConnectTimeout(60000); // 1 minute connect timeout
          request.setReadTimeout(60000); // 1 minute read timeout
        };

    // Build the client for interacting with the service.
    return new CloudHealthcare.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer)
        .setApplicationName("your-application-name")
        .build();
  }

  private static String getAccessToken() throws IOException {
    GoogleCredentials credential =
        GoogleCredentials.getApplicationDefault()
            .createScoped(Collections.singleton(CloudHealthcareScopes.CLOUD_PLATFORM));

    return credential.refreshAccessToken().getTokenValue();
  }
}

Node.js

// Import google-auth-library for authentication.
const {GoogleAuth} = require('google-auth-library');

const searchFhirResourcesPost = async () => {
  const auth = new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/cloud-platform',
    // Set application/fhir+json header because this is a POST request.
    headers: {'Content-Type': 'application/fhir+json'},
  });
  // TODO(developer): uncomment these lines before running the sample
  // const cloudRegion = 'us-central1';
  // const projectId = 'adjective-noun-123';
  // const datasetId = 'my-dataset';
  // const fhirStoreId = 'my-fhir-store';
  // const resourceType = 'Patient';
  const url = `https://healthcare.googleapis.com/v1/projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}/fhirStores/${fhirStoreId}/fhir/${resourceType}/_search`;

  const params = {};
  // Specify search filters in a params object. For example, to filter on a
  // Patient with the last name "Smith", set resourceType to "Patient" and
  // specify the following params:
  // params = {'family:exact' : 'Smith'};
  const client = await auth.getClient();
  const response = await client.request({url, method: 'POST', params});
  const resources = response.data.entry;
  console.log(`Resources found: ${resources.length}`);
  console.log(JSON.stringify(resources, null, 2));
};

searchFhirResourcesPost();

Python

def search_resources_post(project_id, location, dataset_id, fhir_store_id):
    """
    Searches for resources in the given FHIR store. Uses the
    _search POST method and a query string containing the
    information to search for. In this sample, the search criteria is
    'family:exact=Smith' on a Patient resource.

    See https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/healthcare/api-client/v1/fhir
    before running the sample."""
    # Imports Python's built-in "os" module
    import os

    # Imports the google.auth.transport.requests transport
    from google.auth.transport import requests

    # Imports a module to allow authentication using a service account
    from google.oauth2 import service_account

    # Gets credentials from the environment.
    credentials = service_account.Credentials.from_service_account_file(
        os.environ["GOOGLE_APPLICATION_CREDENTIALS"]
    )
    scoped_credentials = credentials.with_scopes(
        ["https://www.googleapis.com/auth/cloud-platform"]
    )
    # Creates a requests Session object with the credentials.
    session = requests.AuthorizedSession(scoped_credentials)

    # URL to the Cloud Healthcare API endpoint and version
    base_url = "https://healthcare.googleapis.com/v1"

    # TODO(developer): Uncomment these lines and replace with your values.
    # project_id = 'my-project'  # replace with your GCP project ID
    # location = 'us-central1'  # replace with the parent dataset's location
    # dataset_id = 'my-dataset'  # replace with the parent dataset's ID
    # fhir_store_id = 'my-fhir-store' # replace with the FHIR store ID
    url = f"{base_url}/projects/{project_id}/locations/{location}"

    fhir_store_path = "{}/datasets/{}/fhirStores/{}/fhir".format(
        url, dataset_id, fhir_store_id
    )

    resource_path = f"{fhir_store_path}/Patient/_search?family:exact=Smith"

    # Sets required application/fhir+json header on the request
    headers = {"Content-Type": "application/fhir+json;charset=utf-8"}

    response = session.post(resource_path, headers=headers)
    response.raise_for_status()

    resources = response.json()
    print(
        "Using POST request, found a total of {} Patient resources:".format(
            resources["total"]
        )
    )

    print(json.dumps(resources, indent=2))

    return resources

検索クエリの作成

クエリ文字列は、URL 形式でエンコードされた一連の name=value ペアです。検索では、すべてのペアが論理 AND と結合されます。各値は、値の論理 OR として扱われる値のカンマ区切りリストにすることができます。たとえば、Patient?key1=value1&key2=value2,value3 は、次の基準を使用して Patient リソースを検索します。

(key1 = value1) AND (key2 = value2 OR key2 = value3)

2 つの name=value ペアの OR を実行する構文はありません。

FHIR リソースタイプでは、FHIR の各バージョンの独自の検索パラメータを定義します。使用可能なパラメータは、各リソースの FHIR 仕様に記載されています。例については、FHIR R4 Patient をご覧ください。パラメータは、機能ステートメントを使用してプログラムで取得できます。Cloud Healthcare API では、ほとんどの検索パラメータがサポートされています。除外される検索パラメータについては、機能ステートメントまたは FHIR 適合性宣言で確認できます。

ページ分けと並べ替え

FHIR 検索結果の各ページで返されるリソースの数は、次の要因によって異なります。

  • _count パラメータ。検索メソッドから返されるリソースの最大数を制御します。たとえば、_count=10 はクエリと一致するリソースを最大 10 個返します。デフォルトは 100 で、許容最大値は 1,000 です。
  • レスポンス データのサイズ。レスポンスのサイズが大きい場合、検索結果のページで _count パラメータで指定した値より少ないリソースが返されることがあります。

検索で 1 ページに収まらないほど多くのリソースが返された場合、レスポンスの Bundle.link フィールドにページ設定 URL が含まれます。このフィールドには複数の値が返される場合があります。Bundle.link.relation = next の値は、対応する Bundle.link.url を使用して次のページを取得できることを示します。

Bundle.total の値は、一致するリソースの合計数を示します。この値は、結果が 1 ページに完全に収まる場合には正確に表示されますが、結果の数が 1 ページよりも大幅に多い場合には概算的な推計値として示されます。多数の結果に一致する検索の正確な合計は、結果がなくなるまで繰り返しページ分けリンクをたどることで取得できます。

ページ分けと検索の合計の詳細については、FHIR 検索を使用したページ分けと検索の合計の実装をご覧ください。

_sort パラメータを使用して結果を並べ替えることができます。このパラメータは、優先順位で並べられた検索パラメータ名のカンマ区切りリストを受け入れます。降順での並べ替えを示す - 接頭辞を使用できます。たとえば、次のクエリは、ステータスの昇順で並べ替えられ、日付の降順、カテゴリの昇順は解除されます。

_sort=status,-date,category

インデックスの遅延

FHIR リソースは非同期でインデックスに登録されるため、リソースが作成または変更されてから変更が検索結果に反映されるまでに、わずかな遅延が発生する場合があります。唯一の例外はリソース ID データで、特別なインデックスとして同期的にインデックスに登録されます。そのため、リソース ID を使用した検索はインデックス登録の遅延の対象ではありません。特別な同期インデックスを使用するには、ID の検索キーワードは identifier=[system]|[value] または identifier=[value] のパターンにする必要があります。次の検索結果パラメータのいずれかを使用できます。

  • _count
  • _include
  • _revinclude
  • _summary
  • _elements

クエリに他の検索パラメータが含まれている場合は、代わりに標準の非同期インデックスが使用されます。なお、特別なインデックスに対する検索は、少数の一致を解決するように最適化されています。ID 検索条件が多数のリソース(2,000 件を超えるリソース)と一致する場合、検索は最適化されません。多数のリソースに一致する検索クエリの場合は、クエリに _sort パラメータを追加することで、特別な同期インデックスの使用を回避できます。デフォルトの並べ替え順を保持する場合は、_sort=-_lastUpdated を使用します。

すべてのリソースタイプでの検索

_id のように先頭に付されたアンダースコアによって識別される検索パラメータは、すべてのリソースタイプに適用されます。これらすべてのリソース パラメータは、リソースタイプ FHIR の仕様に記載されています。

こうした検索パラメータを使用すると、リクエストパスでリソースタイプを省略して、複数のリソースタイプにまたがって検索できます。たとえば、GET .../fhir/Patient?_id=1234 の代わりに GET .../fhir?_id=1234 を使用すると、患者リソースだけでなくすべての FHIR リソース全体を検索できます。このタイプのリクエストで特別なパラメータ _type を使用すると、リソースタイプのカンマ区切りリストに結果を制限できます。たとえば、次のクエリは Observation リソースと Condition リソースに関する一致する結果のみを返します。

GET .../fhir?_tag=active&_type=Observation,Condition

データ型

FHIR によって定義された各検索パラメータには、次のようなプリミティブ型を含むデータが型があります。

  • 文字列
  • 数値
  • 日付

データ型には、次の複合型も含まれます。

  • トークン
  • リファレンス
  • 数量

各データ型には、値を指定する独自の構文が用意されています。各データ型で、検索の実行方法を変更する修飾子がサポートされます。

以下のセクションでは、データ型の使用方法について説明します。その他のデータ型、値の構文、修飾子の詳細については、高度な FHIR 検索機能をご覧ください。

数値

整数値または浮動小数点値を検索します。コンパレータを変更するには、次のいずれかの修飾子で値に接頭辞を付けます。

  • ne
  • lt
  • le
  • gt
  • ge

たとえば、等式の場合は [parameter]=100、100 以上の場合は [parameter]=ge100 を使用します。

日付

任意のタイプの日付、時刻、または期間を検索します。日付パラメータの形式は次のとおりです。

yyyy-mm-ddThh:mm:ss[Z|(+|-)hh:mm]

番号に使用されているのと同じ接頭辞修飾子が適用されます。

文字列

デフォルト設定は、大文字と小文字、アクセント記号、その他の発音区別符号を区別しない接頭辞検索です。

トークン

「code」と完全に一致する文字列を検索します。次の形式を使用して、コードの取得元である値をセットを示す「system」の URI に検索範囲を限定できます

[parameter]=[system]|[code]

たとえば、次の検索では、指定された URI のコーディング システムから取得した値として修飾された場合にのみ、コード 10738-3 との一致が検索されます。

code=http://hl7.org/fhir/ValueSet/observation-codes|10738-3

数量

番号と同じ接頭辞修飾子を使用して数値を検索します。次の形式の値の単位を示す特定のシステムとコードで検索を修飾できます。

[parameter]=[prefix][number]|[system]|[code]

たとえば、次のクエリは、指定した単位系とコードを持つ 9.1 未満の数量値を検索します。

value-quantity=lt9.1|http://unitsofmeasure.org|mg

リファレンス

リソース間の参照を検索します。FHIR ストア内のリソースへの参照には、次のクエリを使用できます。

  • [parameter]=[id]
  • [parameter]=[type]/[id]

[parameter]=[url] を使用して、FHIR ストアの外部に存在する可能性がある URL で参照を指定できます。

検索パラメータの処理

デフォルトでは、検索メソッドは「lenient」処理を適用します。これにより、検索で認識されないパラメータは無視されます。検索メソッドでは、リクエスト内の残りのパラメータを使用して検索を実行し、想定を上回るリソースを返す場合があります。

レスポンスには次の内容が含まれます。

  • Bundle.link.relation = self の値を持つ Bundle.link の値
  • 検索に正常に適用されたパラメータのみが含まれる URL の Bundle.link.url。この値を調べると、パラメータが無視されたかどうかを判断できます。

検索リクエストでリクエスト HTTP ヘッダーを Prefer: handling=strict に設定できます。ヘッダーを設定すると、認識できないパラメータに対して FHIR ストアからエラーが返されます。