如何在HAPI FHIR Plain Server中实现_has反向链查询支持
HAPI FHIR Plain Server 支持
_has反向链查询实现方法 你要处理的这个请求是FHIR标准反向链查询,本质是查满足以下条件的ResearchStudy资源:存在关联的ResearchSubject实例,该实例的study字段指向当前ResearchStudy,且individual字段值为Patient/3635973。
HAPI FHIR本身原生支持_has语法,只是官方Plain Server相关示例较少,不需要自己从头解析参数,按下面配置即可:
1. 开启全局反向链配置
不管你是用JPA模块做持久化,还是自己实现自定义Dao,首先要在服务配置里放开反向链限制:
@Bean public DaoConfig daoConfig() { DaoConfig config = new DaoConfig(); // 开启反向链、反向include支持 config.setAllowMultipleReverseIncludes(true); // 配置允许的反向链最大嵌套层级,单层级反向链设1即可,有多层嵌套需求再往上调,不建议设超过3,避免慢查询打挂服务 config.setReverseChainDepthLimit(2); return config; }
2. 确保关联搜索参数正确注册
_has的语法固定为_has:[关联资源类型]:[关联资源上指向当前资源的搜索参数名]:[关联资源的过滤条件],对应你这个请求拆解后是:
- 关联资源类型:
ResearchSubject - 关联资源上的引用搜索参数:
study(对应ResearchSubject.study字段,指向ResearchStudy) - 关联资源过滤条件:
individual=Patient/3635973(对应ResearchSubject.individual字段,指向Patient)
HAPI的通用查询逻辑会自动处理反向链关联,只要这两个属于ResearchSubject的标准搜索参数已经注册到服务上下文即可:
- 如果你是基于HAPI JPA Starter搭建的服务,启动时会自动加载FHIR标准定义的所有搜索参数,不需要额外配置,直接就能用
- 如果你是从零搭建的Plain Server、没有引入JPA模块,需要手动注册这两个搜索参数:
// 注册ResearchSubject的study引用搜索参数 RuntimeSearchParam studySearchParam = new RuntimeSearchParam(); studySearchParam.setName("study"); studySearchParam.setPath("ResearchSubject.study"); studySearchParam.setType(SearchParamType.REFERENCE); modelConfig.addSearchParam(studySearchParam); // 注册ResearchSubject的individual引用搜索参数 RuntimeSearchParam individualSearchParam = new RuntimeSearchParam(); individualSearchParam.setName("individual"); individualSearchParam.setPath("ResearchSubject.individual"); individualSearchParam.setType(SearchParamType.REFERENCE); modelConfig.addSearchParam(individualSearchParam);
3. 自定义持久层场景的处理方式
如果你没有用HAPI默认的JPA持久化,是自己在ResourceProvider里实现查询逻辑,不需要自己手写HTTP参数解析,HAPI已经提供了参数绑定注解,直接在搜索方法上接收解析好的反向链条件即可:
@Search public IBundleProvider searchStudy( @Count Integer count, @Elements List<String> elements, // 加这个参数,HAPI会自动把所有_has条件解析后传进来 @ReverseChain List<ReverseChainedParameter> reverseChainedParams ) { // 遍历反向链条件拼自己的业务查询逻辑 for (ReverseChainedParameter chainParam : reverseChainedParams) { String targetResourceType = chainParam.getTargetResourceType(); // 这里拿到"ResearchSubject" String refParamName = chainParam.getTargetSearchParameterName(); // 这里拿到"study" Map<String, List<String>> filterConditions = chainParam.getSearchParameters(); // 这里拿到key为"individual",值为["Patient/3635973"]的map // 实现自己的关联查询逻辑即可 } // 按_count分页、按_elements过滤返回字段后返回结果 }
常见踩坑
- 不要搞混
_has的参数顺序:中间的搜索参数一定是关联资源上指向当前资源的参数,不是当前资源指向关联资源的参数,写反会直接查不出结果 - 如果服务开了搜索参数白名单,记得把反向链涉及到的所有关联资源的搜索参数加入白名单,否则会被拦截报“不识别的搜索参数”
- 反向链嵌套深度不要设太大,多表关联查询性能会急剧下降,生产环境建议给关联字段加对应的数据库索引
内容的提问来源于stack exchange,提问作者Eponymous
相关产品推荐
相关产品推荐

