View a markdown version of this page

$bulk-m ember-Match 操作适用于 HealthLake - AWS HealthLake

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

$bulk-m ember-Match 操作适用于 HealthLake

AWS HealthLake 支持异步处理多个成员匹配请求的$bulk-member-match操作。该操作使医疗保健组织能够在单个批量请求中使用人口统计和保险信息,有效地匹配不同医疗保健系统中的数百个成员的唯一标识符。此功能对于大规模的付款人到付款人数据交换、成员过渡和 CMS 合规性要求至关重要,并且符合 FHIR 规范。

注意

$bulk-member-match操作基于FHIR的基本规范,该规范目前处于实验阶段,可能会发生变化。随着规范的发展,此 API 的行为和接口将相应更新。建议开发人员监视 AWS HealthLake 发行说明和相关的 FHIR 规范更新,以随时了解可能影响其集成的任何更改。

当您需要执行以下操作时,此操作特别有用:

  • 在开放注册期间大规模处理成员匹配

  • 促进付款人之间的批量成员过渡

  • Support 支持大规模 CMS 合规数据交换要求

  • 在医疗保健网络中高效匹配成员群组

  • 最大限度地减少 API 调用并提高大批量匹配场景的运营效率

用法

$bulk-member-match操作是使用 POST 方法对组资源调用的异步操作:

POST [base]/Group/$bulk-member-match

提交批量匹配请求后,您可以使用以下方式轮询任务状态:

GET [base]/$bulk-member-match-status/{jobId}

支持的参数

HealthLake 支持以下 FHIR $bulk-member-match 参数:

参数 Type 必需 说明

MemberPatient

病人

包含要匹配的成员的人口统计信息的患者资源。

CoverageToMatch

涵盖

覆盖范围资源,将用于与现有记录进行匹配。

CoverageToLink

涵盖

在匹配过程中要链接的覆盖范围资源。

Consent

同意

还会存储用于授权目的的同意资源。这与不需要征得同意的个人$member-match操作不同。

POST 请求提交批量成员匹配任务

以下示例显示了提交批量成员匹配作业的 POST 请求。每个成员都封装在包含必需的MemberPatientCoverageToMatch、和Consent资源以及可选MemberBundle参数的参数中CoverageToLink

POST [base]/Group/$bulk-member-match Content-Type: application/fhir+json { "resourceType": "Parameters", "parameter": [ { "name": "MemberBundle", "part": [ { "name": "MemberPatient", "resource": { "resourceType": "Patient", "identifier": [ { "system": "http://example.org/patient-id", "value": "patient-0" } ], "name": [ { "family": "Smith", "given": ["James"] } ], "gender": "male", "birthDate": "1950-01-01" } }, { "name": "CoverageToMatch", "resource": { "resourceType": "Coverage", "status": "active", "identifier": [ { "system": "http://example.org/coverage-id", "value": "cov-0" } ], "subscriberId": "sub-0", "beneficiary": { "reference": "Patient/patient123" }, "relationship": { "coding": [ { "system": "http://terminology.hl7.org/CodeSystem/subscriber-relationship", "code": "self" } ] }, "payor": [ { "reference": "Organization/org123" } ] } }, { "name": "Consent", "resource": { "resourceType": "Consent", "status": "active", "scope": { "coding": [ { "system": "http://terminology.hl7.org/CodeSystem/consentscope", "code": "patient-privacy" } ] }, "category": [ { "coding": [ { "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", "code": "IDSCL" } ] } ], "patient": { "reference": "Patient/patient123" }, "performer": [ { "reference": "Patient/patient123" } ], "sourceReference": { "reference": "http://example.org/DocumentReference/consent-source" }, "policy": [ { "uri": "http://hl7.org/fhir/us/davinci-hrex/StructureDefinition-hrex-consent.html#regular" } ], "provision": { "type": "permit", "period": { "start": "2024-01-01", "end": "2025-12-31" }, "actor": [ { "role": { "coding": [ { "system": "http://terminology.hl7.org/CodeSystem/provenance-participant-type", "code": "performer" } ] }, "reference": { "identifier": { "system": "http://hl7.org/fhir/sid/us-npi", "value": "9876543210" }, "display": "Old Health Plan" } }, { "role": { "coding": [ { "system": "http://terminology.hl7.org/CodeSystem/v3-ParticipationType", "code": "IRCP" } ] }, "reference": { "identifier": { "system": "http://hl7.org/fhir/sid/us-npi", "value": "0123456789" }, "display": "New Health Plan" } } ], "action": [ { "coding": [ { "system": "http://terminology.hl7.org/CodeSystem/consentaction", "code": "disclose" } ] } ] } } }, { "name": "CoverageToLink", "resource": { "resourceType": "Coverage", "status": "active", "identifier": [ { "system": "http://example.org/coverage-link-id", "value": "cov-link-0" } ], "subscriberId": "new-sub-0", "beneficiary": { "reference": "Patient/patient123" }, "relationship": { "coding": [ { "system": "http://terminology.hl7.org/CodeSystem/subscriber-relationship", "code": "self" } ] }, "payor": [ { "identifier": { "system": "http://hl7.org/fhir/sid/us-npi", "value": "0123456789" }, "display": "New Health Plan" } ] } } ] } ] }

已完成任务响应,并附有输出

任务完成后,响应将包括任务元数据和一个 FHIR Parameters 资源,其中包含三个对匹配结果进行分类的组资源。

{ "datastoreId": "datastoreId", "jobId": "jobId", "status": "COMPLETED", "submittedTime": "2026-03-20T18:45:26.321Z", "numberOfMembers": 3, "numberOfMembersProcessedSuccessfully": 3, "numberOfMembersWithCustomerError": 0, "numberOfMembersWithServerError": 0, "output": { "resourceType": "Parameters", "meta": { "profile": [ "http://hl7.org/fhir/us/davinci-pdex/StructureDefinition/pdex-parameters-multi-member-match-bundle-out" ] }, "parameter": [ { "name": "MatchedMembers", "resource": { "resourceType": "Group", "id": "group1", "text": { "status": "generated", "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">Matched members group</div>" }, "contained": [ { "resourceType": "Patient", "id": "1", "identifier": [ { "system": "http://example.org/patient-id", "value": "patient-0" } ], "name": [ { "family": "Smith", "given": ["James"] } ], "gender": "male", "birthDate": "1950-01-01" } ], "type": "person", "actual": true, "code": { "coding": [ { "system": "http://hl7.org/fhir/us/davinci-pdex/CodeSystem/PdexMultiMemberMatchResultCS", "code": "match", "display": "Matched" } ] }, "quantity": 1, "member": [ { "entity": { "extension": [ { "url": "http://hl7.org/fhir/us/davinci-pdex/StructureDefinition/base-ext-match-parameters", "valueReference": { "reference": "#1" } } ], "reference": "Patient/patient123" } } ] } }, { "name": "NonMatchedMembers", "resource": { "resourceType": "Group", "id": "Group2", "text": { "status": "generated", "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">Non-matched members group</div>" }, "contained": [ { "resourceType": "Patient", "id": "1", "identifier": [ { "system": "http://example.org/patient-id", "value": "patient-501" } ], "name": [ { "family": "Carter", "given": ["Emily"] } ], "gender": "female", "birthDate": "1985-06-15" } ], "type": "person", "actual": true, "code": { "coding": [ { "system": "http://hl7.org/fhir/us/davinci-pdex/CodeSystem/PdexMultiMemberMatchResultCS", "code": "nomatch", "display": "Not Matched" } ] }, "quantity": 1, "member": [ { "entity": { "extension": [ { "url": "http://hl7.org/fhir/us/davinci-pdex/StructureDefinition/base-ext-match-parameters", "valueReference": { "reference": "#1" } } ], "reference": "Patient/patient123" } } ] } }, { "name": "ConsentConstrainedMembers", "resource": { "resourceType": "Group", "id": "group3", "text": { "status": "generated", "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">Consent constrained members group</div>" }, "contained": [ { "resourceType": "Patient", "id": "1", "identifier": [ { "system": "http://example.org/patient-id", "value": "patient-502" } ], "name": [ { "family": "Nguyen", "given": ["David"] } ], "gender": "male", "birthDate": "1972-11-22" } ], "type": "person", "actual": true, "code": { "coding": [ { "system": "http://hl7.org/fhir/us/davinci-pdex/CodeSystem/PdexMultiMemberMatchResultCS", "code": "consentconstraint", "display": "Consent Constraint" } ] }, "quantity": 1, "member": [ { "entity": { "extension": [ { "url": "http://hl7.org/fhir/us/davinci-pdex/StructureDefinition/base-ext-match-parameters", "valueReference": { "reference": "#1" } } ], "reference": "Patient/123" } } ] } } ] } }

如何 HealthLake 将成员分类为输出组

$bulk-member-match请求中提交的每个成员都将通过顺序管道进行评估。每个步骤的结果决定了将该成员置于哪个输出组中。

  1. 结构验证 — 是否 MemberBundle 符合要求的配置文件? 失败时:错误(不在任何组中)。

  2. 患者匹配 —能否 HealthLake 找到与提交的人口统计数据相匹配的患者? 失败时: NonMatchedMembers.

  3. 承保范围确认 ——能否将 HealthLake 范围缩小到只有一名有效的患者 CoverageToMatch? 失败时: NonMatchedMembers.

  4. 同意评估 —提交的同意书现在是否合格? (状态 = 活跃,期间涵盖当前日期,可以验证执行者)。失败时: ConsentConstrainedMembers.

  5. 成功-所有检查均通过。同意存储在数据存储中。成员已放入 MatchedMembers。

关键原则:一个成员只能出现在一个目的地。第一个失败的步骤决定了位置。未能通过第 2 步或第 3 步的成员永远不会进入该群组 ConsentConstrainedMembers ——该群组专为成功匹配但无法兑现其同意的成员而设。

同意评估详情(步骤 4):

  • 检查 1-同意状态:Consent.status等于 “激活” 吗? 如果不是 → ConsentConstrainedMembers。

  • 支票 2 — 供应期:是否provision.period涵盖当前日期? 如果当前日期早于period.start或之后 period.end → ConsentConstrainedMembers.

  • 检查 3-执行者验证:能否验证Consent.performer参考文献? 如果在数据存储中找不到引用的资源,或者与匹配的患者没有关联 → ConsentConstrainedMembers。

必须通过所有支票才能将成员安置在里 MatchedMembers 面,同意书才能被存储。

覆盖范围匹配行为

在成员匹配期间,CoverageToMatch仅根据响应付款人的数据存储进行验证。 CoverageToLink属于 new/requesting 付款人,且根据旧付款人的数据存储进行验证。包含CoverageToLink在请求中不会影响匹配结果。

申请中的每个 “患者+保险” 组合都是独立处理的。同一位患者可以多次提交不同的保险计划,并且每个参赛作品都会根据其特定的承保范围获得自己的结果。

同意执行者推荐人处理

新的付款人可能会在中发送临时或本地患者推荐信Consent.performer(例如,中使用的同一推荐信Consent.patient)。 HealthLake 会自动解析这些引用:

  • 如果Consent.performer包含与相同的局部参考文献Consent.patient,则在匹配成功后将其 HealthLake 替换为实际匹配的患者参考文献。

  • HealthLake 支持 “患者” RelatedPerson、“从业者” 和 “组织” 类型的表演者引用(包括直接引用和逻辑标识符引用)。 PractitionerRole

  • 如果执行者验证失败(未找到资源或资源与匹配的患者无关),则会将成员置于 ConsentConstrainedMembers 其中,而不是返回错误。

输出组资源

已完成的任务将返回一个包含三个组资源的参数资源:

MatchedMembers Group

包含所有成功匹配的成员的患者推荐信,这些成员的同意在请求时已激活且有效。将为每个匹配的成员创建意见征求资源并将其存储在数据存储中。此组在数据存储中实例化,可以直接与一起使用。$davinci-data-export

NonMatchedMembers Group

包含对未找到唯一匹配项的成员的引用。当数据存储中没有患者与所提供的人口统计数据相匹配,任何匹配的候选患者都没有有效的保险,或者多名患者与人口统计数据相匹配且多名患者具有有效的覆盖范围(模棱两可)时,将成员置于此处。

ConsentConstrainedMembers Group

包含成功匹配(已确认人口统计和覆盖范围)但在请求时无法兑现其同意的成员的患者推荐信。不会为受许可限制的成员存储意见征求资源。匹配的成员身份(MemberIdentifier 和 MemberId)仍包含在内,因此提出请求的付款人知道谁受到了限制。

Group.quantity字段包含其各自组中的成员总数。

小组成员参考资料:

  • Group.member.entity.reference— 对于 MatchedMembers 和 ConsentConstrainedMembers,包含响应付款人系统中匹配成员的患者 ID。对于 NonMatchedMembers,引用包含的输入 “患者”。

  • Group.member.entity.extension (base-ext-match-parameters)— 包含原始输入请求中的患者 ID(请求付款人提交的身份证,源自Patient.idCoverage.beneficiary.reference、或Consent.patient.reference)。

重要

存储的同意资源保留的患者参考信息与申请付款人提交的信息完全相同。 HealthLake 不会自动更新 “同意” 的 “患者” 字段以指向接收数据存储中匹配的患者。

要将存储的同意书链接到匹配的患者,请使用任务输出: MatchedMembers 组中的每个成员都有一个member.entity.reference指向匹配患者的指向,一个 member.entity.extension (base-ext-match-parameters) 指向包含的输入患者。 Cross-reference 这些带有同意的患者字段,用于在您的应用程序层中构建映射。

存储的内容与瞬态存储的内容

下表记录了$bulk-member-match处理期间数据存储中 HealthLake 保留的内容以及仅存在于任务响应中的内容:

资源 已存储? 可以通过 REST 查询吗? 注意

MemberPatient (输入)

仅用于匹配;不用于保存

CoverageToMatch (输入)

仅用于确认承保范围

CoverageToLink (输入)

未针对数据存储进行验证;属于新的付款人

同意(匹配的成员)

是 — GET [base] /Consent/ {id}

按收到请求的付款人收到的款项存储

同意(受限制的成员)

未存储。回复中仍包含成员身份。

MatchedMembers 组(输出)

是 — GET [base] /Group/ {id}

已实例化;可与 $davinci-data-export 配合使用

NonMatchedMembers 群组

仅限 Job 响应

ConsentConstrainedMembers 群组

仅限 Job 响应

与 $davinci-data-export

返回的 MatchedMembers 组资源$bulk-member-match可以直接用于检索批量成员数据的$davinci-data-export操作:

POST [base]/Group/{matched-group-id}/$davinci-data-export GET [base]/Group/{matched-group-id}

这种集成可实现高效的工作流程,您可以首先批量识别匹配的成员,然后使用生成的群组资源导出他们的完整健康记录。

在导出之前使用 $member-remobe

如果您需要在匹配后将特定成员排除在导出范围之外(例如,成员在匹配和导出之间撤消同意),请在 MatchedMembers 群组$member-remove上使用。

重要

通过删除成员会将该成员$member-remove标记为在群组中处于非活动状态,但$davinci-data-export仅在群组更新为 “最终” 状态后才会排除不活跃的成员。如果您调用$davinci-data-export仍处于默认状态的群组,则已移除的成员仍可能出现在导出结果中。

工作流:

  1. POST [base]/Group/{id}/$member-remove— 将成员标记为非活动状态

  2. PUT [base]/Group/{id}— 将群组状态更新为 “最终”

  3. POST [base]/Group/{id}/$davinci-data-export— 导出现在不包括已删除的成员

性能特征

$bulk-member-match操作专为大容量处理而设计,并且是异步运行的:

  • 并@@ :每个数据存储最多 5 个并发操作。

  • 可扩展性:每个请求最多可处理 500 个成员(有效载荷限制 5 MB)。

  • 并行操作:与并行导入、导出或批量删除操作兼容。

Authorization

API 在 FHIR 上使用 SMART 授权协议,其所需范围如下:

  • system/Patient.read— 搜索和匹配患者资源所必需的。

  • system/Coverage.read— 验证覆盖范围信息所必需的。

  • system/Group.write— 创建结果组资源所必需的。

  • system/Organization.read— 视情况而定,如果承保范围涉及组织,则为必填项。

  • system/Practitioner.read— 有条件,如果承保范围涉及从业人员,则为必填项。

  • system/PractitionerRole.read— 视情况而定,如果保险范围涉及从业者的角色,则为必填项。

  • system/Consent.write— 有条件的,如果提供了同意资源,则为必填项。

该操作还支持用于编程 AWS 访问的 IAM 签名版本 4 (Sigv4) 授权。

验证规则

在步骤 1 中,以下验证规则适用于每个 MemberBundle 规则。未通过验证的成员会被报告为错误,并且不会出现在任何输出组中。

MemberPatient

字段如何 HealthLake 使用它如果出现以下情况,则验证失败

name.family

人口统计搜索

缺失

name.given

人口统计搜索

缺失(至少需要一个)

birthDate

人口统计搜索

缺失

gender

人口统计搜索;如果没有,则使用出生性别扩展名

既不存在性别也不存在出生性别(hrex-pat-1)

identifier

在搜索中包含在搜索中;提高信心

从不导致故障(可选)

CoverageToMatch / CoverageToLink

字段如何 HealthLake 使用它如果出现以下情况,则验证失败

status

确认承保范围可付诸行动

缺失

beneficiary

将承保范围与患者候选人联系起来

缺失

payor

存在多个候选人时消除歧义

缺失或不止一个付款人

relationship

确认订阅者与受益人的关系

缺失

identifier (MB) or subscriberId

主要消除歧义的关键

都不在场

字段如何 HealthLake 使用它如果出现以下情况,则验证失败

scope

确认同意范围为患者隐私

缺少或没有患者隐私码

category

确认披露分类

缺失

patient

标识同意主体

缺失

performer

确定谁表示同意

缺失

sourceReference

记录同意来源

缺失

policy.uri

确定数据共享范围

缺失或 URI 未以 #regular 或 #sensitive 结尾

provision.type

必须根据 HreX 同意资料获得 “许可”

缺少或不是 “许可”(包括 “拒绝”)

provision.period

在步骤 4 中针对受同意约束的检查进行了评估

缺失或没有 start/end

status

在步骤 4(不是步骤 1)中进行评估

从不导致步骤 1 失败 — HealthLake 接受任何有效状态并在步骤 4 处进行评估

注意

HRex 同意配置文件使用固定值为 “活跃” 来定义状态。 HealthLake 故意放宽这一限制,使非主动同意获得有意义的分类 (ConsentConstrainedMembers),而不是一揽子验证拒绝。

匹配行为

  • 患者搜索(步骤 2)— 使用 name.family +name.given(精确、不区分大小写)、(精确)、birthDate(精确;如果不存在性别则使用出生性别)和identifier(如果存在则可选)进行 HealthLake 搜索。gender

  • 消除@@ 覆盖范围歧义(步骤 3)— 当找到多个候选患者CoverageToMatch时,使用缩小到一个。如果数据存储中存在与subscriberIdidentifier(MB 类型)和(MB 类型)匹配的活动 Coverage 资源,则覆盖范围为 “有效”。payor

  • 同意评估(步骤 4)— 仅在成功完成唯一匹配后执行。请参阅上面的用户意见征求评估详情部分。

错误处理

该操作处理以下错误情况:

  • 400 错误请求:请求格式无效、缺少必填参数或有效负载超过大小限制(500 个成员或 5 MB)。

  • 422 无法处理的实体:任务执行期间的处理错误。

  • 个人成员错误:当特定成员未能处理时,将继续对剩余成员进行操作,并在 NonMatchedMembers 群组中包含错误详细信息以及相应的原因代码。例如,MemberBundle如果患者缺少该birthDate参数,则会返回以下错误:

    "errors": [ { "memberIndex": 1, "jsonBlob": { "resourceType": "OperationOutcome", "issue": [ { "severity": "error", "code": "invalid", "diagnostics": "MemberPatient.birthDate is required" } ], "statusCode": 400 } } ]

错误详情可通过状态轮询端点获得,包括:

  • numberOfMembersWithCustomerError:存在验证或输入错误的成员数量。

  • numberOfMembersWithServerError:出现服务器端处理错误的成员数。