3. FHIR数据类型的工程含义
在FHIR交换工程中,真正决定接口能否稳定对接的,往往不是资源的大类,而是资源内部这些“小类型”。它们看起来只是字段格式,实际上承载了唯一性、语义、指向、计量、时间窗和排程等关键约束。一旦理解偏差,轻则映射错位,重则导致临床决策依据被误读。本节从工程视角逐一拆解六类高频数据类型,并给出可落地的处理策略。
Identifier:唯一标识不是“随便一个字符串”
Identifier用于表达业务系统中的标识符,如病历号、医保号、检验申请单号。它由system(命名空间URI)、value(值)、type(标识类型)、use(用途,如official、usual)等组成。工程上最常见的陷阱是:只传value不传system,导致两个不同医院的“12345”被系统误判为同一患者。正确做法是把system视为强制语义锚点,例如urn:oid:1.2.156.1001这类机构OID。另一个陷阱是use与type混用:use描述“这个标识在当前场景下是否正式”,type描述“它是什么种类的号”,二者不可互相替代。在患者主索引(EMPI)匹配时,建议把system+value作为联合主键参与比对,而不是仅比对value。
CodeableConcept:编码的“多轨并行”与语义选择
CodeableConcept是一个可携带多个coding的容器,每个coding包含system、code、display,还可带text作为自由文本兜底。它的设计初衷是允许同一概念同时用LOINC、SNOMED CT、ICD-10等不同编码体系表达。工程陷阱集中在三点:第一,把text当作主数据使用,下游无法做结构化统计;第二,多个coding之间语义不一致,例如一个coding写“高血压”,另一个写“糖尿病”,接收方无法判断以哪个为准;第三,忽略system的URI规范,写成“LOINC”而非http://loinc.org。建议在接口契约中明确“首选编码体系+允许的备选体系”,并在映射层做一次语义一致性校验:若多个coding的display差异过大,应触发人工复核而非静默通过。
Reference:指向资源的“软链接”及其完整性风险
Reference用于指向另一个资源,常见形式为Reference(Patient/123)或绝对URL。它可以是“包含式”引用(被引资源随本条一起提交)或“独立式”引用(仅给指针)。工程上最危险的是悬空引用:接收方拿到Observation.subject = Reference(Patient/999),但本地并无Patient/999。FHIR本身不强制引用完整性,这需要交换双方约定。实务中建议:对关键临床资源(如Observation、MedicationRequest)采用包含式提交,或在批量交换前先做资源依赖拓扑排序,确保被引资源先落地。此外,reference中的相对路径依赖服务器基址,跨机构交换时应优先使用绝对URL或逻辑标识(如identifier型引用),避免基址变化导致解析失败。
Quantity:数值、单位与比较语义
Quantity包含value、unit、system、code。陷阱在于“单位看起来一样,语义却不同”:unit是给人看的显示单位,code+system才是机器可比的规范单位。例如血糖value=5.6,若code为mmol/L与mg/dL,临床含义相差近18倍。工程上必须要求system=http://unitsofmeasure.org且code使用UCUM规范写法。另一个易错点是比较类Quantity(如Comparator为<、>),例如“体温<38.5℃”,若忽略comparator直接当等值处理,会丢失临床判断。建议在数据校验层对Quantity做“单位可换算性检查”,无法换算时拒绝入库并告警。
Period与Timing:时间窗与排程的两种表达
Period用start和end表达一个连续时间区间,适合“用药起止”“住院时段”。Timing则用repeat(频率、周期、次数、时长)和event表达离散或重复事件,适合“每日三次、连服七天”。工程陷阱是:把Timing硬塞进Period,或把Period拆成多个event导致语义丢失。例如医嘱“bid×7天”,正确表达是Timing.repeat.frequency=2、period=1、periodUnit=d、boundsDuration=7天;若只写两个event,接收方无法还原“持续七天”的意图。此外,Period的end缺失表示“仍在进行”,不能默认补当前时间;Timing的时区处理也需统一,建议所有时间戳带时区偏移,避免跨时区排程漂移。
工程落地:把类型约束写进接口契约
上述六类类型的问题,单靠开发人员记忆很难保证一致。建议在接口契约(如OpenAPI或FHIR CapabilityStatement)中显式声明:Identifier必须携带system;CodeableConcept至少一个coding且system为白名单URI;Reference在批量交换时采用包含式;Quantity必须使用UCUM code;Period的end缺失语义为“持续中”;Timing优先使用repeat而非event。同时,在数据接入层设置校验规则,对不满足约束的消息返回OperationOutcome并标注具体路径,而不是静默丢弃或强行转换。
总结来看,Identifier解决“是谁”,CodeableConcept解决“是什么”,Reference解决“指向谁”,Quantity解决“多少”,Period与Timing解决“何时”。把这六类类型的约束前置到契约和校验层,FHIR交换才能从“能通”走向“可信”。