搜尋 FHIR 資源

本頁面說明如何在 FHIR 儲存庫中搜尋 FHIR 資源的基本操作說明。搜尋 FHIR 資源是查詢 FHIR 資料並取得洞察的主要方式。

您可以透過下列方式,在 Cloud Healthcare API 中搜尋 FHIR 資源:

本頁面會概述許多常用的搜尋功能,但並非完整列出 Cloud Healthcare API 支援的 FHIR 搜尋規範部分。

使用 FHIR 檢視器

FHIR 檢視器是 Google Cloud 主控台中的頁面,可讓您搜尋並查看 FHIR 資源的內容

如要在 FHIR 儲存庫中搜尋資源,請完成下列步驟:

  1. 前往 Google Cloud 控制台的「FHIR viewer」頁面。

    前往 FHIR 檢視器

  2. 在「FHIR Store」下拉式清單中選取資料集,然後選取資料集中的 FHIR 儲存庫。

  3. 如要篩選資源類型清單,請搜尋要顯示的資源類型:

    1. 按一下「Resource Type」(資源類型) 欄位。

    2. 在隨即出現的「Properties」下拉式清單中,選取「Resource Type」

    3. 輸入資源類型。

    4. 如要搜尋其他資源類型,請從隨即顯示的「運算子」下拉式清單中選取「OR」,然後輸入其他資源類型。

  4. 在資源類型清單中,選取要搜尋的資源類型。

  5. 在資源表的搜尋框中輸入要搜尋的值。

FHIR 檢視器會在表格中顯示搜尋結果。選取資源後,FHIR 檢視器會顯示資源的內容。

查看資源內容時,您可以搜尋資源內的資料。

如要搜尋資源中的資料,請按照下列步驟操作:

  1. 請選取資源。

  2. 在「FHIR viewer」窗格中,按一下「Elements」分頁標籤。

  3. 在搜尋框中輸入要搜尋的值。

下載 FHIR 資源中的二進位資料

如要在 FHIR 檢視器中下載與資源相關聯的可用二進位資料,請按照下列步驟操作:

  1. 請選取資源。

  2. 在「FHIR viewer」窗格中,按一下「Elements」分頁標籤。

  3. 視需要展開元素,以存取必要的資源元素。

  4. 點選「下載檔案」,下載可用的資料。

建立及執行進階搜尋查詢

您可以使用進階搜尋查詢,透過 FHIR 搜尋規格搜尋特定 FHIR 資源。

如要建立進階搜尋查詢,請完成下列步驟:

  1. FHIR 檢視器頁面中,按一下「搜尋」分頁標籤。

  2. 如要建立搜尋查詢,請按一下「開啟查詢建構工具」

    畫面上會顯示「Query Selection」面板。

  3. 在「選取 FHIR 資源類型」清單中,選擇要搜尋的 FHIR 資源類型。

  4. 按一下「繼續」

  5. 從「參數」清單中,選取要用來搜尋資源的參數。

  6. 在「Modifier」清單中,選取要套用至查詢的修飾符。清單只會列出與所選參數資料類型相容的修飾符。

    這是選填項目。如果未選取修飾符,系統會執行相等性檢查。

  7. 在「值」欄位中輸入查詢參數的值。

  8. 如要新增多個參數值,請按一下「OR」。這樣一來,您就能在搜尋查詢中加入多個資源參數值。

    建立搜尋查詢時,查詢會顯示在「查詢預覽」窗格中。如要查看搜尋查詢的完整網址,請按一下「顯示完整路徑」

  9. 如要新增多個參數,請按一下「AND」

  10. 按一下「繼續」

  11. 如要納入搜尋查詢中傳回的資源所參照的資源,請從「已納入的參數」下拉式清單中選擇資源參數。

  12. 如要納入參照搜尋查詢中傳回資源的資源,請從「Reverse included parameters」下拉式清單中選擇資源參數。

  13. 按一下「完成」即可儲存搜尋查詢。

    已儲存的搜尋查詢會顯示在「FHIR 搜尋作業」欄位中。

  14. 如要使用查詢搜尋資源,請按一下「執行搜尋」

    搜尋結果會顯示在「Search results」清單中。如要查看搜尋結果所傳回資源的詳細資料,請在清單中點選所需資源。

  15. 如要將查詢儲存為查詢範本,請按一下「儲存範本」,然後選擇「儲存範本」或「儲存範本為」。系統會提示您輸入查詢的名稱和說明。查詢參數會儲存在範本中,但所有已定義的值都會移除。

搜尋查詢範例

以下範例顯示搜尋查詢,用於搜尋特定醫療服務供應商 (Practitioner/12345) 在 2021 年 8 月的索賠資源:

  • 參數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

您可以在「查詢選取」面板中進行以下設定,並在「查詢預覽」窗格中預覽查詢。查詢會顯示在「FHIR 搜尋作業」欄位中。

FHIR 進階搜尋查詢

編輯搜尋查詢

如要編輯搜尋查詢,請執行下列任一操作:

  • 如要在查詢建構工具中編輯查詢,請按一下「Open Query Builder」
  • 如要手動編輯查詢,請在文字方塊中編輯參數值。

執行查詢範本

如要透過已儲存的範本執行查詢,請完成下列步驟:

  1. 按一下「已儲存的範本」

    系統會顯示「Query Selection」面板的「Search templates」分頁,列出所有已儲存的查詢範本。

  2. 選取要執行的查詢範本,然後按一下「完成」

    範本的搜尋查詢會顯示在「FHIR 搜尋作業」欄位中,但沒有任何值。

  3. 如要定義搜尋查詢的值,請編輯欄位中的參數值。

  4. 按一下「執行搜尋」,使用查詢搜尋資源。

共用 FHIR 資源

您可以分享 FHIR 資源的目前或歷史版本連結。

控制台

  1. 前往 Google Cloud 控制台的「FHIR viewer」頁面。

    前往 FHIR 檢視器

  2. 在「FHIR 儲存庫」選單中選取資料集,然後選取資料集中的 FHIR 儲存庫。

  3. 如要篩選 FHIR 資源類型清單,請搜尋要顯示的資源類型。

  4. 按一下「Resource type」(資源類型) 欄位。

  5. 在隨即出現的「Properties」下拉式清單中,選取「Resource Type」

  6. 輸入 FHIR 資源類型。

  7. 在 FHIR 資源類型清單中,選取所需資源類型。

  8. 在顯示的 FHIR 資源表格中,選取或搜尋資源。

  9. 在「FHIR viewer」窗格中,按一下 「Share」。系統會自動將 FHIR 資源的共用連結複製到剪貼簿。

使用 search 方法

如要使用 REST API 搜尋 FHIR 資源,請使用 projects.locations.datasets.fhirStores.fhir.search 方法。您可以使用 GETPOST 要求呼叫該方法。

使用 search 方法搭配 GET

下列範例說明如何使用 GET 搭配 projects.locations.datasets.fhirStores.fhir.search 方法,在特定 FHIR 儲存庫中搜尋資源。

curl

如要在 FHIR 儲存庫中搜尋資源,請提出 GET 要求,並指定下列資訊:

  • 資料集名稱
  • FHIR 儲存庫的名稱
  • 要搜尋的資源類型
  • 查詢字串,內含您要搜尋的資訊,如「建立搜尋查詢」一節所述
  • 存取權杖

以下範例顯示使用 curlGET 要求,用來搜尋所有姓氏為「Smith」的病患。

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 BundleBundle.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 的 GET 要求,用來搜尋所有姓氏為「Smith」的病患。

$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 BundleBundle.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

使用 search 方法搭配 POST

下列範例說明如何使用 POST 搭配 projects.locations.datasets.fhirStores.fhir.search 方法,在特定 FHIR 儲存庫中搜尋資源。

curl

如要在 FHIR 儲存庫中搜尋資源,請提出 POST 要求,並指定下列資訊:

  • 資料集名稱
  • FHIR 儲存庫的名稱
  • 要搜尋的資源類型
  • 查詢字串,內含您要搜尋的資訊,如「建立搜尋查詢」一節所述
  • 存取權杖

以下範例顯示使用 curlPOST 要求,用來搜尋所有姓氏為「Smith」的病患。

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 BundleBundle.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 的 POST 要求,用來搜尋所有姓氏為「Smith」的病患。

$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 BundleBundle.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

建構搜尋查詢

查詢字串是一系列以網址形式編碼的 name=value 組合。搜尋會將所有組合與邏輯 AND 結合。每個值可為以半形逗號分隔的值清單,並視為這些值的邏輯 OR。舉例來說,Patient?key1=value1&key2=value2,value3 是使用下列條件搜尋病患資源:

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

沒有語法可執行兩個 name=value 組合的 OR

每個 FHIR 資源類型都會在每個 FHIR 版本中定義專屬的搜尋參數。每項資源的 FHIR 規格都會說明可用的參數。如需範例,請參閱 FHIR R4 Patient。您可以透過 功能語句,以程式輔助方式擷取參數。Cloud Healthcare API 支援大多數的搜尋參數;您可以透過功能聲明或 FHIR 符合聲明查看排除條件。

分頁和排序

FHIR 搜尋結果每頁傳回的資源數量取決於下列因素:

  • _count 參數。它會控管從搜尋方法傳回的資源數量上限。舉例來說,_count=10 最多會傳回 10 個與查詢相符的資源。預設值為 100,允許的最大值為 1,000。
  • 回應資料的大小。如果回應大小很大,一頁搜尋結果傳回的資源可能會少於 _count 參數中指定的值。

如果搜尋結果傳回的資源數量超過單頁可容納的資源數量,回應會在 Bundle.link 欄位中加入分頁網址。這個欄位可能會傳回多個值;如果值含有 Bundle.link.relation = next,表示您可以使用對應的 Bundle.link.url 擷取下一頁。

Bundle.total 的值代表相符資源的總數。如果結果完全符合一頁,這個值就會精確,但如果結果數超過一頁,這個值就會變成粗略估計。只要不斷點選分頁連結,直到搜尋結果用盡為止,即可取得相符搜尋結果的確切總數。

如要進一步瞭解分頁和搜尋總數,請參閱「透過 FHIR 搜尋功能實作分頁和搜尋總數」。

您可以使用 _sort 參數排序結果,該參數會以逗號分隔的清單形式接受搜尋參數名稱,並依優先順序排列。您可以使用 - 前置字串來表示遞減順序。舉例來說,下列查詢會依狀態由高至低排序,並以日期由低至高排序來解決平手情形,最後再以類別由高至低排序來解決任何剩餘的平手情形:

_sort=status,-date,category

_sort 僅支援 numberdatastringtokenquantity 類型的搜尋參數。如要使用其他類型的搜尋參數 (例如 reference) 進行排序,請使用 FHIR 自訂搜尋建立 reference 欄位的 string 搜尋參數。

建立索引的延遲時間

FHIR 資源會以非同步方式建立索引,因此在建立或變更資源與變更反映在搜尋結果之間,可能會有一點延遲。唯一的例外狀況是資源 ID 資料,這類資料會同步索引為特殊索引。因此,使用資源 ID 進行搜尋不會受到索引延遲的影響。如要使用特殊的同步索引,識別碼的搜尋字詞應採用 identifier=[system]|[value]identifier=[value] 模式,且可使用下列任一搜尋結果參數:

  • _count
  • _include
  • _revinclude
  • _summary
  • _elements

如果查詢包含任何其他搜尋參數,系統會改用標準非同步索引。請注意,針對特殊索引的搜尋已針對解決少量相符項目進行最佳化。如果 ID 搜尋條件與大量 (超過 2,000 個) 資源相符,系統就不會對搜尋結果進行最佳化。如果搜尋查詢會比對大量資源,您可以在查詢中加入額外的 _sort 參數,避免使用特殊的同步索引。如果您想保留預設排序順序,請使用 _sort=-_lastUpdated

搜尋所有資源類型

某些搜尋參數會在開頭加上底線 (例如 _id),適用於所有資源類型。這些全資源參數列於 FHIR 規格中的「Resource type」

使用這些搜尋參數時,您可以從要求路徑中省略資源類型,藉此跨多種資源類型執行搜尋。舉例來說,使用 GET .../fhir?_id=1234 而非 GET .../fhir/Patient?_id=1234 時,系統會搜尋所有 FHIR 資源,而非只搜尋 Patient 資源。您可以使用這類要求的特殊參數 _type,將結果限制為以半形逗號分隔的資源類型清單。舉例來說,下列查詢只會傳回 ObservationCondition 資源的符合結果:

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]

適用與 number 相同的前置字元修飾符。

字串

預設為前置字串搜尋,不區分大小寫、重音符號或其他變音符號。

權杖

搜尋與「code」完全相符的字串。您可以使用下列格式,將搜尋範圍限定為「系統」的 URI,以表示程式碼取自的值集:

[parameter]=[system]|[code]

舉例來說,下列搜尋會比對代碼 10738-3,但只有在該代碼符合指定 URI 中編碼系統的值時才會比對:

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

數量

使用與 number 相同的前置字串修飾符來搜尋數值。您可以使用特定系統和代碼來限定搜尋,並以以下格式表示值的單位:

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

舉例來說,下列查詢會搜尋指定單位系統和代碼的數量值,且小於 9.1:

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

參考資料

搜尋資源之間的參照。您可以使用下列查詢,取得 FHIR 儲存庫內資源的參照:

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

您可以使用 [parameter]=[url],根據可能位於 FHIR 儲存庫外的網址指定參照。

搜尋參數處理

根據預設,搜尋方法會套用「寬鬆」處理設定,略過搜尋未辨識的參數。搜尋方法會使用要求中的任何剩餘參數執行搜尋,因此可能會傳回比預期更多的資源。

回應內容包括:

  • Bundle.link 中的值,其值為 Bundle.link.relation = self
  • 網址的 Bundle.link.url,僅包含已成功套用至搜尋的參數。您可以檢查這個值,判斷是否有任何參數遭到忽略。

您可以將搜尋要求的 HTTP 標頭設為 Prefer: handling=strict。設定標頭會導致 FHIR 儲存庫針對任何無法辨識的參數傳回錯誤。