חיפוש משאבי FHIR

בדף הזה מוסברות ההוראות הבסיסיות לחיפוש משאבי FHIR בחנות FHIR. חיפוש משאבי FHIR היא הדרך העיקרית לשאילתה ולקבלת תובנות מנתוני FHIR.

אפשר לחפש משאבי FHIR ב-Cloud Healthcare API בדרכים הבאות:

  • שימוש בכלי לצפייה ב-FHIR במסוף Google Cloud .
  • באמצעות השיטה projects.locations.datasets.fhirStores.fhir.search. השיטה מספקת את הדרכים הבאות לחיפוש משאבי FHIR:
    • GET בקשות
    • POST בקשות

בדף הזה מופיע סיכום של הרבה תכונות חיפוש נפוצות, אבל זו לא רשימה מלאה של החלקים במפרט החיפוש של FHIR שנתמכים על ידי Cloud Healthcare API.

שימוש בכלי לצפייה ב-FHIR

הכלי להצגת FHIR הוא דף במסוף Google Cloud שמאפשר לחפש ולהציג את התוכן של משאבי FHIR.

כדי לחפש משאבים במאגר FHIR, מבצעים את השלבים הבאים:

  1. נכנסים לדף FHIR viewer במסוף Google Cloud .

    מעבר לכלי לצפייה ב-FHIR

  2. ברשימה הנפתחת FHIR Store (מאגר FHIR), בוחרים מערך נתונים ואז בוחרים מאגר FHIR במערך הנתונים.

  3. כדי לסנן את רשימת סוגי המשאבים, מחפשים את סוגי המשאבים שרוצים להציג:

    1. לוחצים על השדה סוג המשאב.

    2. ברשימה הנפתחת Properties שמופיעה, בוחרים באפשרות Resource Type.

    3. מזינים סוג משאב.

    4. כדי לחפש סוג משאב אחר, בוחרים באפשרות OR מהרשימה הנפתחת Operators שמופיעה, ואז מזינים סוג משאב אחר.

  4. ברשימת סוגי המשאבים, בוחרים את סוג המשאב שרוצים לחפש.

  5. בתיבת החיפוש של טבלת המשאבים שמופיעה, מזינים את הערך שרוצים לחפש.

תוצאות החיפוש מוצגות בטבלה בכלי להצגת נתוני FHIR. אחרי שבוחרים משאב, הצופה ב-FHIR מציג את התוכן של המשאב.

כשמציגים את התוכן של משאב, אפשר לחפש נתונים בתוך המשאב.

כדי לחפש נתונים בתוך משאב, פועלים לפי השלבים הבאים:

  1. בוחרים משאב.

  2. בחלונית FHIR viewer, לוחצים על הכרטיסייה Elements.

  3. בתיבת החיפוש, מזינים את הערך שרוצים לחפש.

הורדת נתונים בינאריים במשאבי FHIR

כדי להוריד את הנתונים הבינאריים שזמינים ומשויכים למשאב בכלי להצגת FHIR, פועלים לפי השלבים הבאים:

  1. בוחרים משאב.

  2. בחלונית FHIR viewer, לוחצים על הכרטיסייה Elements.

  3. אם צריך, מרחיבים את הרכיבים כדי לגשת לרכיב המשאב הנדרש.

  4. לוחצים על הורדת הקובץ כדי להוריד את הנתונים הזמינים.

יצירה והרצה של שאילתות חיפוש מתקדמות

אפשר להשתמש בשאילתות חיפוש מתקדמות כדי לחפש משאבי FHIR ספציפיים באמצעות מפרט החיפוש של FHIR.

כדי ליצור שאילתת חיפוש מתקדם, מבצעים את השלבים הבאים:

  1. בדף FHIR viewer, לוחצים על הכרטיסייה Search (חיפוש).

  2. כדי ליצור שאילתת חיפוש, לוחצים על פתיחת הכלי ליצירת שאילתות.

    מוצגת החלונית בחירת שאילתה.

  3. מהרשימה Select a FHIR resource type (בחירת סוג משאב FHIR), בוחרים את סוג משאב ה-FHIR שרוצים לחפש.

  4. לוחצים על Continue.

  5. ברשימה פרמטר, בוחרים את הפרמטר שרוצים להשתמש בו כדי לחפש משאבים.

  6. ברשימה Modifier, בוחרים את התוסף שרוצים להחיל על השאילתה. הרשימה כוללת רק משנים שתואמים לסוג הנתונים של הפרמטר שנבחר.

    זו בחירה אופציונלית. אם לא בוחרים משנה, מתבצעת בדיקת שוויון.

  7. בשדה ערך, מזינים את הערך של פרמטר השאילתה.

  8. כדי להוסיף יותר מערך פרמטר אחד, לוחצים על OR. כך אפשר לכלול כמה ערכים של פרמטר המשאב בשאילתת החיפוש.

    בזמן שאתם יוצרים את שאילתת החיפוש, היא מוצגת בחלונית תצוגה מקדימה של השאילתה. כדי לראות את כתובת ה-URL המלאה של שאילתת החיפוש, לוחצים על הצגת הנתיב המלא.

  9. כדי להוסיף עוד פרמטר, לוחצים על וגם.

  10. לוחצים על Continue.

  11. כדי לכלול משאבים שהמשאבים שמוחזרים בשאילתת החיפוש מפנים אליהם, בוחרים את פרמטר המשאב מהתפריט הנפתח פרמטרים כלולים.

  12. כדי לכלול משאבים שמפנים למשאבים שמוחזרים בשאילתת החיפוש, בוחרים את פרמטר המשאב מהתפריט הנפתח פרמטרים הפוכים שכלולים.

  13. לוחצים על סיום כדי לשמור את שאילתת החיפוש.

    שאילתת החיפוש השמורה מוצגת בשדה FHIR search operation.

  14. כדי לחפש משאבים באמצעות השאילתה, לוחצים על הפעלת החיפוש.

    תוצאות החיפוש מוצגות ברשימה תוצאות החיפוש. כדי לראות את הפרטים של משאב שמוחזר בחיפוש, לוחצים על משאב ברשימה.

  15. כדי לשמור את השאילתה כתבנית שאילתה, לוחצים על שמירת תבנית ובוחרים באפשרות שמירת תבנית או שמירת התבנית בשם. תתבקשו להזין שם ותיאור לשאילתה. פרמטרים של שאילתות נשמרים בתבנית, אבל כל הערכים המוגדרים מוסרים.

שאילתת חיפוש לדוגמה

בדוגמה הבאה מוצגת שאילתת חיפוש שמחפשת משאבי Claim מספק שירותים רפואיים ספציפי, Practitioner/12345, לחודש אוגוסט 2021:

  • פרמטר: 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 search operation.

שאילתת חיפוש מתקדם של FHIR

עריכת שאילתות חיפוש

כדי לערוך שאילתת חיפוש, מבצעים אחת מהפעולות הבאות:

  • כדי לערוך את השאילתה בכלי ליצירת שאילתות, לוחצים על Open Query Builder.
  • כדי לערוך את השאילתה באופן ידני, עורכים את ערכי הפרמטר בתיבת הטקסט.

הרצת תבניות של שאילתות

כדי להריץ שאילתה מתבנית שמורה:

  1. לוחצים על תבניות שמורות.

    תוצג הכרטיסייה תבניות חיפוש בחלונית בחירת שאילתה, שבה מוצגות כל תבניות השאילתות השמורות.

  2. בוחרים את תבנית השאילתה שרוצים להריץ ולוחצים על סיום.

    שאילתת החיפוש של התבנית מוצגת בשדה FHIR search operation ללא ערכים.

  3. כדי להגדיר את הערכים של שאילתת החיפוש, עורכים את ערכי הפרמטר בשדה.

  4. לוחצים על Run Search כדי לחפש משאבים באמצעות השאילתה.

שיתוף משאבי FHIR

אפשר לשתף קישור לגרסאות הנוכחיות או ההיסטוריות של משאב FHIR.

המסוף

  1. נכנסים לדף FHIR viewer במסוף Google Cloud .

    מעבר לכלי לצפייה ב-FHIR

  2. בתפריט FHIR store, בוחרים מערך נתונים ואז בוחרים FHIR store במערך הנתונים.

  3. כדי לסנן את רשימת סוגי משאבי FHIR, מחפשים את סוגי המשאבים שרוצים להציג.

  4. לוחצים על השדה סוג המשאב.

  5. ברשימה הנפתחת Properties שמופיעה, בוחרים באפשרות Resource Type.

  6. מזינים סוג משאב FHIR.

  7. ברשימת סוגי משאבי FHIR, בוחרים סוג משאב.

  8. בטבלה של משאבי FHIR שמופיעה, בוחרים משאב או מחפשים משאב.

  9. בחלונית FHIR viewer, לוחצים על Share. קישור לשיתוף משאב ה-FHIR מועתק אוטומטית ללוח.

שימוש בשיטה search

כדי לחפש משאבי FHIR באמצעות ה-API בארכיטקטורת REST, משתמשים ב-method‏ projects.locations.datasets.fhirStores.fhir.search. אפשר להפעיל את השיטה באמצעות בקשות GET או POST.

שימוש בשיטה search עם GET

בדוגמאות הבאות אפשר לראות איך מחפשים משאבים במאגר FHIR נתון באמצעות השיטה projects.locations.datasets.fhirStores.fhir.search עם GET.

curl

כדי לחפש משאבים במאגר FHIR, שולחים בקשת GET ומציינים את הפרטים הבאים:

  • השם של מערך הנתונים
  • השם של מאגר FHIR
  • סוג המשאב לחיפוש
  • מחרוזת שאילתה שמכילה את המידע שאתם מחפשים, כפי שמתואר בקטע יצירת שאילתת חיפוש
  • טוקן גישה

בדוגמה הבאה מוצגת בקשת GET באמצעות curl לחיפוש כל המטופלים ששם המשפחה שלהם הוא 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"

אם הבקשה מצליחה, השרת מחזיר את התגובה כ-FHIR Bundle בפורמט JSON. הערך של Bundle.type הוא searchset ותוצאות החיפוש הן רשומות במערך Bundle.entry. בדוגמה הזו, הבקשה מחזירה משאב Patient יחיד, כולל הנתונים שבתוך המשאב:

{
  "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
  • סוג המשאב לחיפוש
  • מחרוזת שאילתה שמכילה את המידע שאתם מחפשים, כפי שמתואר בקטע יצירת שאילתת חיפוש
  • טוקן גישה

בדוגמה הבאה מוצגת בקשת GET באמצעות Windows PowerShell לחיפוש כל המטופלים ששם המשפחה שלהם הוא 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

אם הבקשה מצליחה, השרת מחזיר את התגובה כ-FHIR Bundle בפורמט JSON. הערך של Bundle.type הוא searchset ותוצאות החיפוש הן רשומות במערך Bundle.entry. בדוגמה הזו, הבקשה מחזירה משאב Patient יחיד, כולל הנתונים שבתוך המשאב:

{
  "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,
    responseType: 'json',
  });
  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

בדוגמאות הבאות אפשר לראות איך מחפשים משאבים במאגר FHIR נתון באמצעות השיטה projects.locations.datasets.fhirStores.fhir.search עם POST.

curl

כדי לחפש משאבים במאגר FHIR, שולחים בקשת POST ומציינים את הפרטים הבאים:

  • השם של מערך הנתונים
  • השם של מאגר FHIR
  • סוג המשאב לחיפוש
  • מחרוזת שאילתה שמכילה את המידע שאתם מחפשים, כפי שמתואר בקטע יצירת שאילתת חיפוש
  • טוקן גישה

בדוגמה הבאה מוצגת בקשת POST באמצעות curl לחיפוש כל המטופלים ששם המשפחה שלהם הוא 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"

אם הבקשה מצליחה, השרת מחזיר את התגובה כ-FHIR Bundle בפורמט JSON. הערך של Bundle.type הוא searchset ותוצאות החיפוש הן רשומות במערך Bundle.entry. בדוגמה הזו, הבקשה מחזירה משאב Patient יחיד, כולל הנתונים שבתוך המשאב:

{
  "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
  • סוג המשאב לחיפוש
  • מחרוזת שאילתה שמכילה את המידע שאתם מחפשים, כפי שמתואר בקטע יצירת שאילתת חיפוש
  • טוקן גישה

בדוגמה הבאה מוצגת בקשת POST באמצעות Windows PowerShell לחיפוש כל המטופלים ששם המשפחה שלהם הוא 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

אם הבקשה מצליחה, השרת מחזיר את התגובה כ-FHIR Bundle בפורמט JSON. הערך של Bundle.type הוא searchset ותוצאות החיפוש הן רשומות במערך Bundle.entry. בדוגמה הזו, הבקשה מחזירה משאב Patient יחיד, כולל הנתונים שבתוך המשאב:

{
  "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',
  });
  // 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'};

  try {
    const client = await auth.getClient();
    const response = await client.request({
      url,
      method: 'POST',
      headers: {
        'Content-Type': 'application/fhir+json',
      },
      params,
      responseType: 'json',
    });
    const resources = response.data.entry || [];
    console.log('Resources found: ' + resources.length);
    console.log(JSON.stringify(resources, null, 2));
  } catch (error) {
    console.error(
      `Error searching ${resourceType} resources:`,
      error.response ? error.response.data : error.message
    );
  }
};

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 שמקודדים בפורמט של כתובת URL. חיפוש משלב את כל הזוגות עם AND לוגי. כל ערך יכול להיות רשימה של ערכים שמופרדים באמצעות פסיקים, והמערכת מתייחסת אליהם כאופרטור לוגי OR של הערכים האלה. לדוגמה, Patient?key1=value1&key2=value2,value3 הוא חיפוש של משאבים למטופלים לפי הקריטריונים הבאים:

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

אין תחביר לביצוע OR של שני זוגות name=value.

כל סוג של משאב FHIR מגדיר פרמטרים משלו לחיפוש בכל גרסה של FHIR. הפרמטרים הזמינים מתועדים במפרט FHIR לכל משאב. לדוגמה, ראו FHIR R4 Patient. אפשר לאחזר את הפרמטרים באופן פרוגרמטי באמצעות הצהרת היכולת. ‫Cloud Healthcare API תומך ברוב פרמטרי החיפוש. אפשר למצוא החרגות בהצהרת היכולות או בהצהרת התאימות ל-FHIR.

חלוקה לדפים ומיון

מספר המשאבים שמוחזרים בכל דף של תוצאות החיפוש ב-FHIR תלוי בגורמים הבאים:

  • הפרמטר _count. הוא קובע את המספר המקסימלי של משאבים שמוחזרים משיטת החיפוש. לדוגמה, הפקודה _count=10 מחזירה לכל היותר 10 משאבים שתואמים לשאילתה. ברירת המחדל היא 100 והערך המקסימלי המותר הוא 1,000.
  • גודל נתוני התגובה. אם גודל התשובה גדול, יכול להיות שדף של תוצאות חיפוש יחזיר פחות משאבים מהערך שצוין בפרמטר _count.

אם החיפוש מחזיר יותר משאבים ממספר המשאבים שנכנסים בדף אחד, התשובה כוללת כתובת URL של חלוקה לדפים בשדה Bundle.link. יכול להיות שיוחזרו כמה ערכים בשדה הזה. הערך עם Bundle.link.relation = next מציין שאפשר להשתמש בערך התואם Bundle.link.url כדי לאחזר את הדף הבא.

הערך של Bundle.total מציין את המספר הכולל של מקורות שתואמים לחיפוש. הערך הזה מדויק אם התוצאות נכנסות כולן לדף אחד, אבל הוא הופך לאומדן גס ככל שמספר התוצאות גדול יותר מדף אחד. כדי לקבל סכום מדויק של חיפוש שתואם להרבה תוצאות, צריך ללחוץ שוב ושוב על הקישורים של המספור לדפים עד שכל התוצאות מוצגות.

מידע נוסף על הגדרת מעברי עמוד וסיכום תוצאות החיפוש זמין במאמר בנושא הטמעה של מעברי עמוד וסיכום תוצאות החיפוש באמצעות חיפוש FHIR.

אפשר למיין את התוצאות באמצעות הפרמטר _sort, שמקבל רשימה מופרדת בפסיקים של שמות פרמטרים לחיפוש, לפי סדר העדיפות. אפשר להשתמש בקידומת - כדי לציין סדר יורד. לדוגמה, השאילתה הבאה ממיינת לפי סטטוס בסדר עולה, ואם יש כמה רשומות עם אותו סטטוס היא ממיינת לפי תאריך בסדר יורד, ואם יש כמה רשומות עם אותו סטטוס ואותו תאריך היא ממיינת לפי קטגוריה בסדר עולה:

_sort=status,-date,category

הפרמטר _sort נתמך רק בפרמטרים של חיפוש מהסוגים number,‏ data,‏ string,‏ token ו-quantity. כדי למיין באמצעות סוגים אחרים של פרמטרים לחיפוש (לדוגמה, reference), צריך להשתמש בחיפושים מותאמים אישית ב-FHIR כדי ליצור, לדוגמה, פרמטר לחיפוש string בשדה reference.

השהיה בהוספה לאינדקס

משאבי FHIR עוברים אינדוקס באופן אסינכרוני, ולכן יכול להיות שיהיה עיכוב קל בין הזמן שבו משאב נוצר או משתנה לבין הזמן שבו השינוי משתקף בתוצאות החיפוש. היוצא מן הכלל היחיד הוא נתוני מזהי משאבים, שמקוטלגים באופן סינכרוני כאינדקס מיוחד. כתוצאה מכך, חיפוש באמצעות מזהה משאב לא כפוף לעיכוב באינדוקס. כדי להשתמש באינדקס הסינכרוני המיוחד, מונח החיפוש של המזהה צריך להיות בתבנית identifier=[system]|[value] או identifier=[value], ואפשר להשתמש בכל אחד מהפרמטרים הבאים של תוצאות החיפוש:

  • _count
  • _include
  • _revinclude
  • _summary
  • _elements

אם השאילתה מכילה פרמטרים אחרים של חיפוש, המערכת תשתמש במקום זאת באינדקס אסינכרוני רגיל. שימו לב שהחיפוש באינדקס המיוחד מותאם למציאת מספר קטן של התאמות. החיפוש לא ממוטב אם קריטריוני החיפוש של המזהה תואמים למספר גדול (כלומר, יותר מ-2,000) של משאבים. כדי למנוע שימוש באינדקס הסינכרוני המיוחד בשאילתת חיפוש שתתאים למספר גדול של משאבים, אפשר לכלול בשאילתה פרמטר נוסף _sort. משתמשים ב-_sort=-_lastUpdated אם רוצים לשמור על סדר המיון שמוגדר כברירת מחדל.

חיפוש בכל סוגי מקורות המידע

פרמטרים מסוימים של חיפוש, שמוצגים עם קו תחתון מוביל כמו _id, חלים על כל סוגי המשאבים. הפרמטרים האלה שרלוונטיים לכל המשאבים מפורטים במפרט FHIR בקטע Resource type.

כשמשתמשים בפרמטרים האלה לחיפוש, אפשר לבצע חיפוש בכמה סוגים של משאבים על ידי השמטת סוג המשאב מנתיב הבקשה. לדוגמה, שימוש ב-GET .../fhir?_id=1234 במקום ב-GET .../fhir/Patient?_id=1234 יחפש בכל משאבי FHIR ולא רק במשאב Patient. אפשר להשתמש בפרמטר המיוחד _type עם סוג הבקשה הזה כדי להגביל את התוצאות לרשימה של סוגי משאבים שמופרדים בפסיקים. לדוגמה, השאילתה הבאה מחזירה רק תוצאות תואמות למשאבים Observation ו-Condition:

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

סוגי הנתונים

לכל פרמטר חיפוש שמוגדר על ידי FHIR יש סוג נתונים, כולל סוגים פרימיטיביים כמו:

  • String
  • מספר
  • תאריך

סוגי הנתונים כוללים גם את הסוגים המורכבים הבאים:

  • אסימון
  • חומרי עזר
  • כמות

לכל סוג נתונים יש תחביר משלו לציון ערכים. כל סוג נתונים תומך במאפיינים שמשנים את אופן החיפוש.

בקטעים הבאים מוסבר איך להשתמש בסוגי נתונים. פרטים נוספים על סוגי נתונים, תחביר ערכים ומשנים זמינים במאמר בנושא תכונות מתקדמות של חיפוש FHIR.

מספר

חיפושים של ערכים מסוג מספר שלם או מספר עשרוני. כדי לשנות את האופרטור להשוואה, מוסיפים לאחד מהערכים את אחד מהמשנים הבאים:

  • ne
  • lt
  • le
  • gt
  • ge

לדוגמה, משתמשים ב-[parameter]=100 כדי לציין שוויון, או ב-[parameter]=ge100 כדי לציין ערך שגדול מ-100 או שווה לו.

תאריך

חיפושים לפי תאריך, שעה או תקופה. הפורמט של פרמטר התאריך הוא:

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

אותם משנים של קידומות שמשמשים למספר חלים גם כאן.

String

ברירת המחדל היא חיפוש לפי קידומת שלא רגיש לאותיות רישיות או קטנות, לסימני הטעמה או לסימנים דיאקריטיים אחרים.

אסימון

חיפוש התאמה מדויקת למחרוזת של 'קוד'. אפשר להגדיר את היקף החיפוש ל-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] כדי לציין הפניות לפי כתובת URL שיכולות להיות מחוץ למאגר FHIR.

טיפול בפרמטרים של חיפוש

כברירת מחדל, שיטת החיפוש מחילה טיפול 'סלחני', שמתעלם מפרמטרים שהחיפוש לא מזהה. שיטת החיפוש מבצעת את החיפוש באמצעות כל הפרמטרים שנותרו בבקשה, ולכן יכול להיות שיוחזרו יותר משאבים מהצפוי.

התשובה כוללת את הפרטים הבאים:

  • ערך בעמודה Bundle.link עם ערך של Bundle.link.relation = self
  • Bundle.link.url של כתובת URL שמכילה רק את הפרמטרים שהוחלו על החיפוש בהצלחה. אפשר לבדוק את הערך הזה כדי לדעת אם המערכת התעלמה מפרמטרים כלשהם.

אפשר להגדיר את כותרת ה-HTTP של הבקשה ל-Prefer: handling=strict בבקשת חיפוש. הגדרת הכותרת גורמת למאגר FHIR להחזיר שגיאה בכל פרמטר לא מזוהה.