BigQuery로 FHIR 리소스 변경사항 스트리밍

이 페이지에서는 FHIR 리소스가 생성, 업데이트, 패치 또는 삭제될 때마다 FHIR 리소스를 BigQuery 테이블로 자동으로 내보내도록 FHIR 저장소를 구성하는 방법을 설명합니다. 이 프로세스를 BigQuery 스트리밍이라고 합니다.

BigQuery 스트리밍을 사용하여 다음을 수행할 수 있습니다.

  • 거의 실시간으로 FHIR 저장소의 데이터를 BigQuery 데이터 세트와 동기화하기
  • 데이터를 분석하려고 할 때마다 BigQuery로 내보낼 필요 없이 FHIR 데이터에 대해 복잡한 수행하기

쿼리 성능을 개선하고 비용을 줄이기 위해서는 BigQuery 스트리밍을 파티션을 나눈 테이블로 구성할 수 있습니다. 자세한 내용은 파티션을 나눈 테이블로 FHIR 리소스 스트리밍하기를 참조하세요.

시작하기 전에

FHIR 리소스를 BigQuery로 내보내기를 읽고 내보내기 프로세스가 어떻게 작동하는지 숙지하세요.

제한사항

Cloud Storage에서 FHIR 리소스를 가져오는 경우 변경사항이 BigQuery로 스트리밍되지 않습니다.

BigQuery 권한 설정

BigQuery 스트리밍을 사용 설정하려면 Cloud Healthcare 서비스 에이전트 서비스 계정에 추가 권한을 부여해야 합니다. 자세한 내용은 FHIR 저장소 BigQuery 권한을 참조하세요.

FHIR 저장소에서 BigQuery 스트리밍 구성

BigQuery 스트리밍을 사용 설정하려면 FHIR 스토어에서 StreamConfigs 객체를 구성하세요. StreamConfigs에서 resourceTypes[] 배열을 구성하여 BigQuery 스트리밍이 적용되는 FHIR 리소스 유형을 제어할 수 있습니다. resourceTypes[]을 지정하지 않으면 BigQuery 스트리밍은 모든 FHIR 리소스 유형에 적용됩니다.

BigQueryDestination처럼 StreamConfigs에서 사용할 수 있는 다른 구성에 대한 설명은 FHIR 리소스 내보내기를 참조하세요.

다음 샘플은 기존 FHIR 저장소에서 BigQuery 스트리밍을 사용 설정하는 방법을 보여줍니다.

콘솔

Google Cloud 콘솔을 사용하여 기존 FHIR 저장소에서 BigQuery 스트리밍을 구성하려면 다음 단계를 완료합니다.

  1. Google Cloud 콘솔에서 데이터 세트 페이지로 이동합니다.

    데이터 세트로 이동

  2. 수정할 FHIR 저장소가 포함된 데이터 세트를 선택합니다.

  3. 데이터 스토어 목록에서 수정할 FHIR 저장소를 선택합니다.

  4. BigQuery 스트리밍 섹션에서 다음 단계를 완료하세요.

    1. 새 스트리밍 구성 추가를 클릭합니다.
    2. 새 스트리밍 구성 섹션에서 찾아보기를 클릭하여 변경된 FHIR 리소스를 스트리밍할 BigQuery 데이터 세트를 선택하세요.
    3. 스키마 유형 드롭다운에서 BigQuery 테이블의 출력 스키마를 선택합니다. 사용 가능한 스키마는 다음과 같습니다.
      • 분석. FHIR 기반 SQL 문서를 기반으로 하는 스키마. BigQuery는 테이블당 10,000개의 열만 허용하므로 Parameters.parameter.resource, Bundle.entry.resource, Bundle.entry.response.outcome 필드의 스키마는 생성되지 않습니다.
      • 분석 V2. 분석 스키마와 유사한 스키마로, 다음이 지원됩니다. 분석 V2 스키마는 분석 스키마보다 대상 테이블에서 더 많은 공간을 사용합니다.
    4. 재귀 구조 깊이 슬라이더에서 깊이 수준을 선택하여 출력 스키마에서 모든 재귀 구조의 깊이를 설정합니다. 기본적으로 재귀 값은 2입니다.
    5. FHIR 리소스 유형 선택 목록에서 스트리밍할 리소스 유형을 선택합니다.
  5. 완료를 클릭하여 스트리밍 구성을 저장합니다.

gcloud

gcloud CLI는 이 작업을 지원하지 않습니다. 대신 Google Cloud 콘솔, curl, PowerShell 또는 원하는 언어를 사용하세요.

REST

기존 FHIR 저장소에서 BigQuery 스트리밍을 구성하려면 projects.locations.datasets.fhirStores.patch 메서드를 사용하세요.

다음 샘플에서는 resourceTypes[] 배열을 지정하지 않으므로, 모든 FHIR 유형에서 BigQuery 스트리밍이 활성화됩니다.

요청 데이터를 사용하기 전에 다음을 바꿉니다.

  • PROJECT_ID: Google Cloud 프로젝트의 ID
  • LOCATION: 데이터 세트 위치
  • DATASET_ID: FHIR 저장소의 상위 데이터 세트
  • FHIR_STORE_ID: FHIR 저장소 ID
  • BIGQUERY_DATASET_ID: FHIR 리소스 변경사항을 스트리밍하는 기존 BigQuery 데이터 세트의 이름
  • SCHEMA_TYPE: SchemaType 열거형 값. 다음 값 중 하나를 사용합니다.
    • ANALYTICS. FHIR 기반 SQL 문서를 기반으로 하는 스키마. BigQuery는 테이블당 10,000개의 열만 허용하므로 Parameters.parameter.resource, Bundle.entry.resource, Bundle.entry.response.outcome 필드의 스키마는 생성되지 않습니다.
    • ANALYTICS_V2. ANALYTICS와 유사한 스키마로서 다음에 대한 지원이 추가됨

      ANALYTICS_V2ANALYTICS보다 대상 테이블에서 더 많은 공간을 사용합니다

      .
  • WRITE_DISPOSITION: WriteDisposition 열거형 값. 다음 값 중 하나를 사용합니다.
    • WRITE_EMPTY. 대상 BigQuery 테이블이 비어 있는 경우에만 데이터를 내보냄
    • WRITE_TRUNCATE. FHIR 리소스를 작성하기 전에 BigQuery 테이블에서 기존 데이터 모두 삭제
    • WRITE_APPEND. BigQuery 테이블에 데이터 추가

JSON 요청 본문:

{
  "streamConfigs": [
    {
      "bigqueryDestination": {
        "datasetUri": "bq://PROJECT_ID.BIGQUERY_DATASET_ID",
        "schemaConfig": {
          "schemaType": "SCHEMA_TYPE",
        },
        "writeDisposition": "WRITE_DISPOSITION"
      }
    }
  ]
}

요청을 보내려면 다음 옵션 중 하나를 선택합니다.

curl

요청 본문을 request.json 파일에 저장합니다. 터미널에서 다음 명령어를 실행하여 현재 디렉터리에 이 파일을 만들거나 덮어씁니다.

cat > request.json << 'EOF'
{
  "streamConfigs": [
    {
      "bigqueryDestination": {
        "datasetUri": "bq://PROJECT_ID.BIGQUERY_DATASET_ID",
        "schemaConfig": {
          "schemaType": "SCHEMA_TYPE",
        },
        "writeDisposition": "WRITE_DISPOSITION"
      }
    }
  ]
}
EOF

그런 후 다음 명령어를 실행하여 REST 요청을 전송합니다.

curl -X PATCH \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID?updateMask=streamConfigs"

PowerShell

요청 본문을 request.json 파일에 저장합니다. 터미널에서 다음 명령어를 실행하여 현재 디렉터리에 이 파일을 만들거나 덮어씁니다.

@'
{
  "streamConfigs": [
    {
      "bigqueryDestination": {
        "datasetUri": "bq://PROJECT_ID.BIGQUERY_DATASET_ID",
        "schemaConfig": {
          "schemaType": "SCHEMA_TYPE",
        },
        "writeDisposition": "WRITE_DISPOSITION"
      }
    }
  ]
}
'@  | Out-File -FilePath request.json -Encoding utf8

그런 후 다음 명령어를 실행하여 REST 요청을 전송합니다.

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

Invoke-WebRequest `
-Method PATCH `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID?updateMask=streamConfigs" | Select-Object -Expand Content

API 탐색기

요청 본문을 복사하고 메서드 참조 페이지를 엽니다. 페이지 오른쪽에 API 탐색기 패널이 열립니다. 이 도구를 사용하여 요청을 보낼 수 있습니다. 요청 본문을 이 도구에 붙여넣고 다른 필수 필드를 입력한 후 실행을 클릭합니다.

다음과 비슷한 JSON 응답이 수신됩니다.

FhirStore 리소스에서 필드를 구성한 경우 응답에도 표시됩니다.

기본적으로 FHIR 리소스 변경사항을 BigQuery로 스트리밍하면 스트리밍되는 각 리소스에 대해 가 생성됩니다. 이 뷰에는 다음과 같은 속성이 있습니다.

  • BigQuery 데이터 세트의 리소스 및 리소스 테이블과 같은 이름을 갖습니다. 예를 들어 환자 리소스를 스트리밍하면 Patient라는 테이블이 Patientview라는 뷰와 함께 생성됩니다.
  • 이전 버전 모두가 아닌 리소스의 현재 버전만 포함됩니다.

파티션을 나눈 테이블로 FHIR 리소스 스트리밍

FHIR 리소스를 BigQuery 파티션을 나눈 테이블로 내보내려면 FHIR 저장소의 lastUpdatedPartitionConfig 필드에서 TimePartitioning 열거형을 설정하세요.

파티션을 나눈 테이블은 BigQuery 시간 단위로 파티션을 나눈 테이블처럼 작동합니다. 파티션을 나눈 테이블에는 FHIR 리소스의 meta.lastUpdated 필드에서 생성된 meta.lastUpdated 열과 중복되는 lastUpdated라는 추가 열이 있습니다. BigQuery는 lastUpdated 열을 사용하여 시간, 일, 월, 연도를 기준으로 테이블의 파티션을 나눕니다.

파티션 세부사항을 선택하는 방법에 대한 권장사항은 일, 시간, 월, 연도별 파티션 나누기 선택을 참조하세요.

파티션을 나누지 않은 기존 BigQuery 테이블은 파티션을 나눈 테이블로 변환할 수 없습니다. 환자 리소스 변경사항을 파티션을 나누지 않은 Patients 테이블로 내보낸 다음 나중에 동일한 BigQuery 데이터 세트로 내보내는 테이블 파티션 나누기를 사용하여 새 FHIR 저장소를 만들어도, Cloud Healthcare API는 파티션을 나누지 않은 Patients 테이블로 여전히 데이터를 내보냅니다. 파티션을 나눈 테이블 사용을 시작하려면 기존 Patients 테이블을 삭제하거나 다른 BigQuery 데이터 세트를 사용하세요.

기존 FHIR 저장소 구성에 파티션 나누기를 추가하는 경우에도 파티션을 나누지 않은 기존 테이블로 계속 내보낼 수 있습니다. 하지만 파티션 나누기는 새 테이블에만 적용됩니다.

다음 샘플은 기존 FHIR 저장소의 파티션을 나눈 테이블에 BigQuery 스트리밍을 사용 설정하는 방법을 보여줍니다.

콘솔

Google Cloud 콘솔과 gcloud CLI는 이 작업을 지원하지 않습니다. 대신 curl, PowerShell 또는 사용자가 선호하는 언어를 사용합니다.

gcloud

Google Cloud 콘솔과 gcloud CLI는 이 작업을 지원하지 않습니다. 대신 curl, PowerShell 또는 사용자가 선호하는 언어를 사용합니다.

REST

기존 FHIR 저장소의 파티션을 나눈 테이블로 BigQuery 스트리밍을 구성하려면 projects.locations.datasets.fhirStores.patch 메서드를 사용하세요.

요청 데이터를 사용하기 전에 다음을 바꿉니다.

  • PROJECT_ID: Google Cloud 프로젝트의 ID
  • LOCATION: 데이터 세트 위치
  • DATASET_ID: FHIR 저장소의 상위 데이터 세트
  • FHIR_STORE_ID: FHIR 저장소 ID
  • BIGQUERY_DATASET_ID: FHIR 리소스 변경사항을 스트리밍하는 기존 BigQuery 데이터 세트의 이름
  • SCHEMA_TYPE: SchemaType 열거형 값. 다음 값 중 하나를 사용합니다.
    • ANALYTICS. FHIR 기반 SQL 문서를 기반으로 하는 스키마. BigQuery는 테이블당 10,000개의 열만 허용하므로 Parameters.parameter.resource, Bundle.entry.resource, Bundle.entry.response.outcome 필드의 스키마는 생성되지 않습니다.
    • ANALYTICS_V2. ANALYTICS와 유사한 스키마로서 다음에 대한 지원이 추가됨

      ANALYTICS_V2ANALYTICS보다 대상 테이블에서 더 많은 공간을 사용합니다

      .
  • TIME_PARTITION_TYPE: 내보낸 FHIR 리소스를 분할할 세부사항. 다음 값 중 하나를 사용합니다.
    • HOUR: 시간별로 데이터 파티션 나누기
    • DAY: 일별로 데이터 파티션 나누기
    • MONTH: 월별로 데이터 파티션 나누기
    • YEAR: 연도별로 데이터 파티션 나누기
  • WRITE_DISPOSITION: WriteDisposition 열거형 값. 다음 값 중 하나를 사용합니다.
    • WRITE_EMPTY. 대상 BigQuery 테이블이 비어 있는 경우에만 데이터를 내보냄
    • WRITE_TRUNCATE. FHIR 리소스를 작성하기 전에 BigQuery 테이블에서 기존 데이터 모두 삭제
    • WRITE_APPEND. BigQuery 테이블에 데이터 추가

JSON 요청 본문:

{
  "streamConfigs": [
    {
      "bigqueryDestination": {
        "datasetUri": "bq://PROJECT_ID.BIGQUERY_DATASET_ID",
        "schemaConfig": {
          "schemaType": "SCHEMA_TYPE",
          "lastUpdatedPartitionConfig": {
            "type": "TIME_PARTITION_TYPE"
          }
        },
        "writeDisposition": "WRITE_DISPOSITION"
      }
    }
  ]
}

요청을 보내려면 다음 옵션 중 하나를 선택합니다.

curl

요청 본문을 request.json 파일에 저장합니다. 터미널에서 다음 명령어를 실행하여 현재 디렉터리에 이 파일을 만들거나 덮어씁니다.

cat > request.json << 'EOF'
{
  "streamConfigs": [
    {
      "bigqueryDestination": {
        "datasetUri": "bq://PROJECT_ID.BIGQUERY_DATASET_ID",
        "schemaConfig": {
          "schemaType": "SCHEMA_TYPE",
          "lastUpdatedPartitionConfig": {
            "type": "TIME_PARTITION_TYPE"
          }
        },
        "writeDisposition": "WRITE_DISPOSITION"
      }
    }
  ]
}
EOF

그런 후 다음 명령어를 실행하여 REST 요청을 전송합니다.

curl -X PATCH \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID?updateMask=streamConfigs"

PowerShell

요청 본문을 request.json 파일에 저장합니다. 터미널에서 다음 명령어를 실행하여 현재 디렉터리에 이 파일을 만들거나 덮어씁니다.

@'
{
  "streamConfigs": [
    {
      "bigqueryDestination": {
        "datasetUri": "bq://PROJECT_ID.BIGQUERY_DATASET_ID",
        "schemaConfig": {
          "schemaType": "SCHEMA_TYPE",
          "lastUpdatedPartitionConfig": {
            "type": "TIME_PARTITION_TYPE"
          }
        },
        "writeDisposition": "WRITE_DISPOSITION"
      }
    }
  ]
}
'@  | Out-File -FilePath request.json -Encoding utf8

그런 후 다음 명령어를 실행하여 REST 요청을 전송합니다.

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

Invoke-WebRequest `
-Method PATCH `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID?updateMask=streamConfigs" | Select-Object -Expand Content

API 탐색기

요청 본문을 복사하고 메서드 참조 페이지를 엽니다. 페이지 오른쪽에 API 탐색기 패널이 열립니다. 이 도구를 사용하여 요청을 보낼 수 있습니다. 요청 본문을 이 도구에 붙여넣고 다른 필수 필드를 입력한 후 실행을 클릭합니다.

다음과 비슷한 JSON 응답이 표시됩니다.

파티션을 나눈 테이블 쿼리

파티션을 나눈 테이블을 쿼리할 때 쿼리 비용을 줄이려면 WHERE 절을 사용하여 시간 단위로 필터링합니다.

예를 들어 PartitionType enum을 DAY로 설정했다고 가정해 보겠습니다. 특정 날짜에 변경된 환자 리소스에 대해 Patients 테이블을 쿼리하려면 다음 쿼리를 실행합니다.

SELECT * FROM `PROJECT_ID.BIGQUERY_DATASET.Patients`
  WHERE DATE(lastUpdated) = 'YYYY-MM-DD'

분석에서 분석 V2로 마이그레이션

어떤 메서드를 사용해도 기존 BigQuery 데이터 세트를 Analytics 스키마에서 Analytics V2 스키마로 마이그레이션할 수 없으며 다음이 포함됩니다.

  • BigQuery에서 테이블의 스키마 유형 변경
  • 기존 FHIR 스트리밍 구성에서 스키마 유형 변경

이는 Analytics 스키마에서 FHIR 확장 프로그램의 BigQuery 테이블 열이 NULLABLE 모드로 설정되어 있고, 반면에 Analytics V2 스키마에서는 REPEATED로 설정되어 있기 때문입니다. BigQuery에서는 열 모드를 NULLABLE에서 REPEATED로 변경하는 것이 허용되지 않습니다. 따라서 두 스키마 유형은 호환되지 않습니다.

내보낸 FHIR 리소스의 스키마 유형을 Analytics에서 Analytics V2로 마이그레이션하려면, 업데이트된 스키마 유형의 새 스트리밍 구성을 사용하여 FHIR 리소스를 새 BigQuery 데이터 세트로 내보내야 합니다. 이렇게 하려면 다음 단계를 실행하세요.

  1. 새 BigQuery 데이터 세트를 만듭니다.

  2. BigQuery 데이터 세트에 대한 권한을 설정합니다.

  3. 스키마 유형을 Analytics V2로 설정하여 FHIR 스토어에 새 스트리밍 구성을 추가합니다.

  4. 다음 설정을 사용하여 기존 FHIR 데이터를 내보내 기존 데이터를 백필합니다. Google Cloud 콘솔, Google Cloud CLI 또는 REST API를 사용하여 이러한 설정을 구성하는 방법에 대한 안내는 FHIR 리소스 내보내기를 참조하세요. 다음 설정이 REST API에 적용됩니다.

BigQuery에서 원본 BigQuery 데이터 세트의 일부 또는 전체 FHIR 리소스에 해당하는 뷰가 새 데이터 세트에서 누락될 수 있습니다. 이 문제를 해결하려면 FHIR 리소스 뷰 만들기 누락을 참조하세요.

FHIR 스트리밍 문제해결

리소스 변경사항이 BigQuery로 전송될 때 오류가 발생하면 오류가 Cloud Logging에 로깅됩니다. 자세한 내용은 Cloud Logging에서 오류 로그 보기를 참조하세요.

NULLABLE에서 REPEATED로 열을 변환할 수 없음

이 오류는 반복 확장으로 인해 발생합니다. 이 오류를 해결하려면 ANALYTICS_V2 스키마 유형을 사용합니다. 이미 ANALYTICS_V2를 사용 중이면 두 확장 프로그램 간에 충돌이 발생하거나 확장 프로그램과 다른 필드 간에 충돌이 발생할 수 있습니다.

열 이름은 확장 URL에서 마지막 / 문자 다음에 오는 텍스트에서 생성됩니다. 확장 프로그램 URL이 /resource_field name 같은 값으로 끝나면 충돌이 발생할 수 있습니다.

이 오류가 다시 발생하지 않도록 하려면 필드 이름이 작성하려는 리소스 필드와 동일한 경우 확장 프로그램을 사용하지 마세요.

FHIR 리소스 뷰 만들기 누락

FHIR 리소스를 스트리밍하기 전에 FHIR 리소스를 BigQuery로 일괄 내보내기하는 경우 BigQuery는 FHIR 리소스에 대한 뷰를 만들지 않습니다.

예를 들어 다음과 같은 상황에서는 Encounter 리소스에 대한 뷰가 표시되지 않을 수 있습니다.

  1. FHIR 저장소에서 BigQuery 스트리밍을 구성한 다음 REST API를 사용하여 환자 리소스를 만듭니다.

    BigQuery는 환자 리소스의 테이블과 뷰를 만듭니다.

  2. Encounter 리소스를 이전 단계와 동일한 BigQuery 데이터 세트로 일괄적으로 내보냅니다.

    BigQuery는 Encounter 리소스의 테이블을 만듭니다.

  3. REST API를 사용하여 Encounter 리소스를 만듭니다.

    이 단계가 끝나면 Encounter 리소스에 대한 BigQuery 뷰가 생성되지 않습니다.

이 문제를 해결하려면 다음 쿼리를 사용하여 뷰를 만듭니다.

SELECT
    * EXCEPT (_resource_row_id)
FROM (
  SELECT
    ROW_NUMBER() OVER(PARTITION BY id ORDER BY meta.lastUpdated DESC, commitTimestamp DESC) as _resource_row_id,
    *
    FROM `PROJECT_ID.BIGQUERY_DATASET_ID.RESOURCE_TABLE` AS p
) AS p
WHERE
  p._resource_row_id=1
  AND
  NOT EXISTS (
  SELECT
    *
  FROM
    UNNEST(p.meta.tag)
  WHERE
    code = 'DELETE');

다음을 바꿉니다.

  • PROJECT_ID: Google Cloud 프로젝트의 ID입니다.
  • BIGQUERY_DATASET_ID: FHIR 리소스를 일괄적으로 내보낸 BigQuery 데이터 세트의 ID입니다.
  • RESOURCE_TABLE: 뷰를 만들려는 FHIR 리소스에 해당하는 테이블의 이름입니다.

뷰를 만든 후 FHIR 리소스에 대한 변경사항을 계속 스트리밍할 수 있으며 이에 따라 뷰가 업데이트됩니다.

다음 단계

FHIR 리소스 변경사항 스트리밍 사용 사례에 대한 튜토리얼은 BigQuery로 FHIR 리소스 스트리밍 및 동기화를 참조하세요.