产品: MongoDB Atlas、 MongoDB Atlas Search
合作伙伴: openEHR
解决方案概述
openEHR 是一种结构化临床记录的方法,即使应用程序和数据库不断发展,其医学含义也能保持一致。它将记录的稳定技术结构与用于对观察、药物或诊断等现实世界概念进行建模的临床定义分开。
从技术上讲,openEHR 是一个模型驱动的 EHR 架构。其参考模型定义了临床记录的稳定结构,而原型和模板则添加了临床含义和实施约束。其主节点 (primary node in the replica set)记录单位是COMPOSITION ,这是一份分层的临床文档,其内容可通过 AQL 查询。 AQL 独立于存储模型。它将类似SQL 的子句与分层路径和基于嵌套临床结构的CONTAINS 谓词相结合。有效地扩展这些查询可能是一个挑战。
在实践中,openEHR存储库通常需要支持以下查询族。第一个对应于单个患者检索,示例打开已知患者的图表或检索一个 EHR 中的特定临床文档。第二个涉及跨患者操作检索,示例建立队列、查找满足安全规则的患者、生成工作列表或在提供护理期间识别类似病例。这些操作查询必须靠近应用程序工作流程运行,并且延迟较低且可预测。
许多实现都在努力有效地支持这两种查询模式。关系方法可以很好地用于患者范围的检索,但大规模的跨患者查询通常会通过连接、模式流失和模板变化带来压力。将这些工作负载转移到单独的分析平台有助于进行回顾性分析,但会造成重复,增加延迟,分散管理和Atlas 审核跟踪,并削弱统一 AQL查询接口的目标。当文档被过度展平时,它还可以删除相关的临床上下文。
协调临床查询系列
该解决方案通过MongoDB上的文档优先、半扁平化持久化模型解决了该问题。半扁平化意味着我们将每个元素展平为大量中的一个节点,但每个元素都保留原始结构中的完整JSON有效负载。文档优先意味着每个 openEHR 组合都保留为一个MongoDB文档,而不是分解为每个原型一个表或每个路径一行。同时,组合被物化为可重建的节点大量,从而能够在不放弃组合作为操作单元的情况下实现基于路径的高效查询。
每个存储节点都保留以下关键元素:
本地临床子树,因此原始含义和上下文仍然可用。
位置元元数据,因此可以重建结构和排序。
反向 AQL 路径,可高效匹配可变深度路径约束。
反向路径是通用查询键,用于跨患者范围和跨患者执行路线有效地评估结构谓词。它支持跨不同执行策略的路径约束匹配,包括搜索索引中基于正则表达式的匹配和通配符式路径解析。当谓词使用其他文本路径组件或文本条件时,可以应用相同的查询模式。
通过此模型,AQL 子句可以确定性地编译到MongoDB查询阶段。 FROM、CONTAINS 和 WHERE 约束成为节点路径和值的目标谓词。这种方法保持了组合作为主节点 (primary node in the replica set)临床容器的完整性,同时仍然使扩展的操作检索实用。
图 1。半扁平化组合的表示形式,其中每个节点都包含自己的上下文和值以及反向 AQL 路径
注意
有关架构和评估的已发布简明摘要,请阅读经过同行评审的会议摘要。有关完整设计,包括半扁平化持久性模型、确定性 AQL 到MQL编译以及基准测试详情,请阅读完整的技术论文。
按工作负载路由
对于许多存储库,单个半展平集合和通配符索引就足够了。对于更大型的部署,该模型可以使用精简搜索投影,其中仅包含广泛的跨患者筛选所需的数据。然后按作用域路由查询执行。精简搜索投影是一个较小的派生集合,仅存储广泛的跨患者筛选所需的节点字段。它不会替换主合成文档。它降低了索引广度和广泛操作查询的搜索费用。
因此,它提供了以下模式:
患者范围的查询在主组合集合上运行,使用有针对性的索引,例如
ehr_id和reversed_path等字段上的复合索引。跨患者查询针对更精简的投影运行,将路径约束编译为通配符或反向路径上的匹配项,并将值谓词编译为相等、范围或搜索操作符。
此执行模型提供单个查询接口,允许根据工作负载大小和选择性使用不同的物理访问权限路径。
为什么支持操作同类群组查询很重要
现代临床应用程序越来越需要同一平台上的两个查询系列。临床医生可能需要立即打开一份患者记录并提出以下问题:
哪些患者在给定时间窗口内接受了某种药物?
哪些患者符合协议或安全规则?
以前有哪些案例在临床上与本案例相似?
这些操作问题需要答案,而不需要通过重复的 ETL 循环将数据推送到单独的系统中。
文档优先的半扁平化模型保留了 openEHR 的优势,并使这些工作负载变得实用。它将组合保持为权威操作单位,通过可重建的结构保持临床保真度,并避免迫使应用程序团队在以患者为中心的存储和单独的跨患者平台之间进行选择。较小的存储库可以保持简单,使用一个半扁平化集合。较大的存储库可以添加较小的投影,以降低广泛操作筛选的费用。
在我们的评估中,这种方法在两种工作负载类型中都保持了较低的端到端延迟,即使在大规模扩展下,患者范围和跨患者查询的响应时间也很短。这种效率验证了其作为 openEHR 存储库的实用基础,该存储库必须支持从一个平台进行操作检索、来源感知处理、语义丰富和AI驱动的工作流程。
注意
生产证明点:此架构在生产中的一个拥有超过 1.2{76,00} 十亿个持久文档的存储库上进行了验证。
您可以使用 kehrnel 来探索这种模式,这是一个用于文档优先临床数据策略的实验性参考运行时和工具包。
采用这种方法可带来以下实际好处:
一种可重建的半扁平模型,可保留合成保真度。
高效进行患者范围的查询,而无需强制对临床文档进行关系分解。
支持跨患者操作检索,而无需默认为仓库优先架构。
为应用程序团队提供一个可操作的查询界面,而不是重复的存储和支离破碎的逻辑。
降低 ETL开销、管理偏差和总拥有费用的途径。
什么是 Kernel?为什么使用它?
Kehrnel 是一个策略运行时,可将医疗保健数据模型转化为操作功能。 Kernel 的存在是因为仅仅定义医疗保健数据模型是不够的。团队还需要一种可重复的方法来验证数据,将其转换为可操作的表示,提取数据,查询数据,维护数据,并随着需求的变化而发展数据。如果没有该执行层,模型通常只是文档、存储模式或孤立的规范。
目标比构建 openEHR引擎更广泛。 Kehrnel 提供了一种可重复的文档优先方法,使医疗保健数据模型跨 API、工具和AI工作流程可执行、可检查和可重用。随着时间的推移,相同的运行时模式可以支持其他模型系列和操作策略,包括 FHIR、合成数据工作流、语义目录、自然语言检索和其他特定领域的工具。
Kernel 围绕公开的工作流程设计,可以根据每个持久性策略的需求进行自定义。每个策略都可以定义自己的激活、验证、摄取、转换、查询、合成数据和维护操作,同时仍然使用一致的运行时模型。
Kehrnel 从 openEHR 入手,因为 openEHR 是一个要求严格、语义丰富的模型。它包括原型、模板、路径、术语和复杂的查询行为。这使其成为证明模型驱动的运行时方法的坚实基础。
对于此解决方案,Kehrnel 充当文档优先持久性模式的参考运行时和工具包。
图 2。 Kernel CLI屏幕截图
参考架构
图 3 显示了该策略在 kehrnel 中的端到端流程,从规范的 openEHR 输入到路由查询执行。
图 3。 AQL 编译器和路由运行时 (kehrnel)
1层:数据源从规范的 openEHR 组合、操作模板的模型目录以及用于扩展测试的可选合成数据开始。 OPT 是从原型和模板派生的已编译运行时工件。操作系统使用 OPT 进行验证和路径感知处理。
2层:转换管道将每个传入组合转换为此策略使用的持久表示形式。半展平步骤会扫描组合层次结构,应用路径和代码编码,并使用映射规则来物化可查询节点。结果为每个组合生成一个半扁平化MongoDB文档,其中存储的节点保留本地临床子树、位置元元数据和反向路径键。
3层:字典和映射存储此策略所需的助手工件。_codes 和_shortcuts 支持紧凑路径解析和编码。映射存储驱动转换和查询编译的特定于策略的规则。
层:4 MongoDB集合显示持久性选项。主节点 (primary node in the replica set)组合集合存储半展平组合文档,并通过ehr_id 和cn.p 上的复合索引提供患者范围的执行。对于大型存储库,可选的搜索集合存储跨患者筛选所需的节点数据点的精简投影。该集合使用MongoDB Atlas Search 进行索引。双集合模式可缩小搜索映射范围并降低搜索费用。
5层:查询引擎是 kehrnel 解析和路由 AQL 的地方。运行时接受 AQL声明,验证 AST,解析别名和安全投影,检测查询是患者范围的还是跨患者的,并发出适当的MQL路由。当查询包含ehr_id 时,运行时会通过组合物集合发出患者范围的聚合管道,通常使用$match $project、 、$sort 和$limit 等阶段。当查询是跨患者时,运行时会在复合过滤内使用embeddedDocument wildcard、range 、 和equals 等操作符,通过细长投影发出搜索优先管道。当template/time/order 谓词是匹配友好时,它可以在基本集合上保留一些跨患者查询。
6层:运行时接口,通过 kehrnel CLI和HTTP API公开此策略。 CLI支持环境设置、策略激活、编译和查询执行等操作符工作流程。该API为集成、自动化和交互式文档公开了相同的运行时功能。
这种分层设计为应用程序团队提供了一个逻辑操作查询界面,并根据存储库大小、查询范围和工作负载选择性启用了不同的访问权限路径。
数据模型方法
将每个组合存储为一个MongoDB文档,并以半展平形式持久保存。每个存储节点包含:
本地临床子树
反向路径键
用于重建的位置元元数据
这种结构使模型成为文档优先且可扩展查询。您可以避免创建“每个原型一个表”的布局,并强制每个查询仅使用原始的嵌套JSON形状。
在此模型中,openEHR 路径保持为一流路径。持久化文档将组合作为操作单位,节点大量为编译器提供了确定性的结构来查询。
以下简化文档显示了一个可读的持久化组合示例。它的格式便于解释,因此字段名称和路径值比紧凑生产编码更容易理解。
{ "_id": "...", "ehr_id": "patient-001", "composition_id": "c-001", "template_id": "openEHR-EHR-COMPOSITION.vaccination_list.v0", "version": 1, "cn": [ { "p": "ACTION.medication.v1.SECTION.immunisation_list.v0.COMPOSITION.vaccination_list.v0", "kp": "content[0]/items[0]", "pi": [0,0], "bk": "b1", "data": { "time": { "value": "2026-01-15T10:30:00Z" }, "other_participations": { "performer": { "identifiers": { "id": "038321545" } } }, "code": { "value": "J07BX03" } } } ] }
如何阅读本文档
一个MongoDB文档代表一个 openEHR 组合。 cn大量存储从该组合中提取的可查询节点。每个节点在 data 中保留一棵本地临床子树,在 p 中保留反向路径键以及 kp、pi 和 bk 等位置元元数据,以便可以重建原始结构。
公开示例以可读形式显示路径键,以使转换更易于理解。在生产中,您可以将相同的路径存储为紧凑的字典编码令牌,以减少路径大小和索引占用空间
反向路径编码
存储的路径字段表示键优化。参考模型属性和原型节点标识符构建openEHR 路径。该解决方案使用反向存储路径,允许使用前缀友好匹配而不是前导通配符扫描来评估包含约束。此设置适用于患者范围路由中基于标准正则表达式的匹配,以及搜索路由中的通配符式匹配。
确定性 AQL 到MQL转换
AQL 独立于存储模型,因此确定性编译非常有效。 SQL子句转换为MQL ,如下所示:
FROM和CONTAINS成为结构路径谓词。WHERE成为匹配节点有效负载上的值谓词。SELECT变为投影。ORDER BY变为排序。
以下示例说明了 AQL查询。
SELECT e/ehr_id/value AS ehrId, c/uid/value AS compositionId, med_ac/description[at0017]/items[at0140]/items[at0141]/value/defining_code/code_string AS locationCode FROM EHR e CONTAINS COMPOSITION c[openEHR-EHR-COMPOSITION.vaccination_list.v0] CONTAINS ( CLUSTER adminInfo[openEHR-EHR-CLUSTER.admin_salut.v0] AND SECTION[openEHR-EHR-SECTION.immunisation_list.v0] AND ACTION med_ac[openEHR-EHR-ACTION.medication.v1] ) WHERE med_ac/time/value >= '2000-04-13T07:54:16.345Z' AND med_ac/time/value <= '2026-02-13T07:54:16.345Z' AND adminInfo/items[at0007]/items[at0014]/value/defining_code/code_string = 'E08019820' AND med_ac/other_participations/performer/identifiers/id = '038321545' ORDER BY med_ac/time/value DESC
此 AQL 要求的内容
此查询结合了结构约束和基于值的约束。 CONTAINS 子句定义了所需的 openEHR 结构,在本例中是包含管理集群和药物动作的疫苗组合。然后,WHERE 子句添加有关动作时间、执行者标识符和管理代码的谓词。
此查询类型受益于确定性编译。它表达了分层临床结构和节点本地值的条件。
编译器如何将 AQL 映射到MQL
已编译的MQL遵循与 AQL 相同的逻辑:
顶级
ehr_id过滤将查询设为患者范围。$all子句要求 AQL 描述的所有结构分支存在于同一组合中。每个
$elemMatch将一个路径谓词及其值谓词绑定到同一存储节点。p上的谓词是结构CONTAINS逻辑的编译形式。数据下的谓词是
WHERE条件的编译形式。在完整管道中,编译器会添加与
SELECT和ORDER BY相对应的投影和排序阶段。
下一个示例显示了从上述 AQL查询生成的简化的患者范围MQL模式。它说明了编译器逻辑,而不是逐字节运行时有效负载。
// Simplified compiler output for a single-EHR query. // Projection and sorting stages are omitted here for clarity. db.compositions.aggregate([ { "$match": { "ehr_id": "b416bc97-de39-43f5-9d47-712af6688947~r1", "cn": { "$all": [ { "$elemMatch": { "p": { "$regex": /^ACTION\.medication\.v1(?:\.[^.]+)*\.SECTION\.immunisation_list\.v0(?:\.[^.]+)*\.COMPOSITION\.vaccination_list\.v0$/ }, "data.time.value": { "$gte": ISODate("2000-04-13T07:54:16.345Z"), "$lte": ISODate("2026-02-13T07:54:16.345Z") }, "data.other_participations.performer.identifiers.id": "038321545" } }, { "$elemMatch": { "p": { "$regex": /^at0014\.at0007\.CLUSTER\.admin_salut\.v0(?:\.[^.]+)*\.COMPOSITION\.vaccination_list\.v0$/ }, "data.value.defining_code.code_string": "E08019820" } } ] } } } ]);
相同的逻辑如何移动到搜索路由
逻辑转换在跨患者路由中保持不变。区别在于物理执行。编译器的目标不是匹配主成分集合,而是 Slim 搜索投影。反向路径上的结构约束成为通配符筛选器,值谓词成为范围和相等筛选器。
下一个示例显示了根据未绑定到患者的 AQL 生成的MQL模式。和以前一样,它说明了编译器逻辑,而不是逐字节的运行时有效负载。
{ "$search": { "index": "search_nodes_index", "compound": { "filter": [ { "embeddedDocument": { "path": "sn", "operator": { "compound": { "filter": [ { "wildcard": { "path": "sn.p", "query": "ACTION.medication.v1*SECTION.immunisation_list.v0*COMPOSITION.vaccination_list.v0" } }, { "range": { "path": "sn.data.time.value", "gte": ISODate("2000-04-13T07:54:16.345Z"), "lte": ISODate("2025-04-13T07:54:16.345Z") } }, { "equals": { "path": "sn.data.other_participations.performer.identifiers.id", "value": "038321545" } } ] } } } } ] } } }
重复结构和相同路径同级结构
某些 openEHR 结构可以包含具有相同有效路径的重复同级节点,示例重复的 EVENTs。这些情况要求编译器将谓词推得更深,以便相同的重复项满足条件。在标准聚合中,这意味着 $elemMatch 的嵌套更深。在搜索路由中,等效项是 embeddedDocument,它将多个条件绑定到同一嵌入式大量元素。
构建解决方案
使用此存储库中提供的 kehrnel 作为此模式的参考运行时和工具包。 Kehrnel 提供了策略生命周期、验证流程、半扁平化管道和 AQL 编译路径,用于摄取规范的 openEHR 组合并通过正确的执行路径路由操作查询。
激活时,Kehrnel 通过 manifest.json 公开策略,使用 defaults.json 作为激活基线,使用 schema.json 验证覆盖,并应用策略实施和 spec.json 描述的存储和索引计划。推荐的路径是让 kehrnel 从活动配置创建集合和B-Tree索引,而不是先在MongoDB中手动创建。
该存储库将 kehrnel 定位为用于演示、教学、快速原型设计和概念验证的实验运行时。要在自己的环境中重现此解决方案,请按照以下步骤操作:
克隆 GitHub存储库并启动 kehrnel
克隆存储库,并使用./startKehrnel 启动运行时。该入口点会自动准备本地环境,使首次运行变得简单。
git clone https://github.com/mongodb-industry-solutions/kehrnel cd kehrnel ./startKehrnel export RUNTIME_URL="${RUNTIME_URL:-http://localhost:8080}" Alternative direct API entrypoint: uvicorn kehrnel.api.app:app --reload --port 8080
初创企业后,确认运行时可访问,并使用 kehrnel 作为其余工作流程的控制平面。
启动后,kehrnel 会在路由 http://localhost:8080 / 指南公开 Docusaurus站点。图4 显示了该站点。
图 4。 Kernel 文档
发现并激活策略
Kernel 支持多种环境、域和策略。在本演练中,将显式选择 openehr 域和 openehr.rps_dual 策略。
使用 src/kehrnel/engine/strategies/openehr/rps_dual/defaults.json 作为基线配置,并仅在要更改集合名称、字段标签、搜索支持、字典、分隔符、编码策略或映射时添加小型覆盖文件。
激活是 kehrnel 从活动策略配置中具体化已配置集合和B-Tree索引的步骤。对于打包的参考示例,激活覆盖文件将 strategy 指向打包的投影映射。然后根据策略的激活设置应用字典引导程序。
注意
mkdir -p .kehrnel Local plaintext MongoDB bindings for the walkthrough cat > .kehrnel/bindings.mongo.yaml <<EOF db: provider: mongodb uri: ${MONGODB_URI} database: ${MONGODB_DB} EOF Packaged activation override for the reference dual-collection example kehrnel core env activate \ --env dev \ --domain openehr \ --strategy openehr.rps_dual \ --config src/kehrnel/engine/strategies/openehr/rps_dual/samples/reference/activation.config.json \ --allow-plaintext-bindings \ --bindings .kehrnel/bindings.mongo.yaml \ --force Ensure bundled dictionaries are present kehrnel run ensure_dictionaries --env dev --domain openehr Generate the Atlas Search definition derived from the active mappings kehrnel strategy build-search-index \ --env dev \ --domain openehr \ --strategy openehr.rps_dual \ --out .kehrnel/search-index.json
准备模板、映射和规范组合
使用 src/kehrnel/engine/strategies/openehr/rps_dual/samples 下策略拥有的示例资产或您自己的规范 openEHR 输入。
使用 OPT 模板验证或生成乐曲。
如果您希望通过驱动摄取和搜索索引生成的相同配置来构建搜索端集合,请使用打包的投影映射。
SAMPLES_ROOT="src/kehrnel/engine/strategies/openehr/rps_dual/samples/reference" Inspect the packaged reference assets ls "$SAMPLES_ROOT/templates" ls "$SAMPLES_ROOT/queries" ls "$SAMPLES_ROOT/envelopes" ls "$SAMPLES_ROOT/projection_mappings.json" \ "$SAMPLES_ROOT/search_index.definition.json" \ "$SAMPLES_ROOT/manifest.json" Optional: generate and validate a sample composition from a packaged OPT kehrnel common generate -- \ -t "$SAMPLES_ROOT/templates/sample_laboratory_v0_4.opt" \ -o .kehrnel/composition.json \ --random kehrnel common validate -- \ -c .kehrnel/composition.json \ -t "$SAMPLES_ROOT/templates/sample_laboratory_v0_4.opt" \ --stats Optional: generate a starter source-to-canonical mapping skeleton kehrnel common map-skeleton -- \ "$SAMPLES_ROOT/templates/sample_laboratory_v0_4.opt" \ -o .kehrnel/mapping.skeleton.yaml \ --macros
摄取组合物
通过该策略摄取组合物。打包的 NDJSON 信封是规范的 openEHR 组合包装器,其中包括屏蔽的组合以及 ehr_id、template_id、composition_version 和 time_committed 等元数据。
此处使用 kehrnel 运行 ingest,而本演练从规范的 openEHR 信封开始,需要策略来生成半扁平化的基本文档,并且当模板存在映射时,还需要生成可选的搜索端投影文档。
下面的本地文件标志只是一个护栏,允许运行时从工作树读取打包的 NDJSON示例。
当模板存在映射时,kehrnel 还会在 compositions_search 中创建可选的搜索端文档。如果模板不存在映射,则会跳过该 sidecar,而不是发出空数组。
The CLI expands the local NDJSON into documents before sending the request. kehrnel run ingest \ --env dev \ --domain openehr \ --strategy openehr.rps_dual \ --set file_path="$SAMPLES_ROOT/envelopes/all.ndjson"
编译和检查 AQL
在执行之前先编译代表性 AQL。
确认解析的范围、发出的MQL和所选的执行路径。
此编译步骤是该模式的关键操作契约。应用程序保留在 AQL 上,而 kehrnel 则根据存储模型处理确定性转换和执行规划。
Compile only: inspect the execution plan without running the query kehrnel core env compile-query \ --env dev \ --domain openehr \ --aql "$SAMPLES_ROOT/queries/patient_laboratory_by_ehr.aql" kehrnel core env compile-query \ --env dev \ --domain openehr \ --aql "$SAMPLES_ROOT/queries/cross_patient_laboratory_by_performing_centre.aql"
运行操作查询
在同一环境中运行患者范围的查询和跨患者查询。此执行演示了该模式的核心价值:一个可操作的查询界面,运行时为工作负载选择正确的物理执行路径。
对于患者范围的查询,运行时可以使用带索引的 $match、$project、$sort 和 $limit 阶段以主半展平集合为目标。对于更广泛的操作检索,当查询结构受益时,运行时可以通过面向搜索的路径进行路由。
Execute both representative queries kehrnel core env query \ --env dev \ --domain openehr \ --aql "$SAMPLES_ROOT/queries/patient_laboratory_by_ehr.aql" kehrnel core env query \ --env dev \ --domain openehr \ --aql "$SAMPLES_ROOT/queries/cross_patient_laboratory_by_performing_centre.aql"
探索生成的工件
检查生成的MongoDB文档、可选的 搜索端投影和Atlas Search索引定义,以验证文档优先设计。
您可以看到规范组合如何保持源输入,半展平形式如何支持确定性查询,以及映射如何驱动搜索端投影而不是盲目复制整个文档。
Inspect the generated base and search-side documents mongosh "$MONGODB_URI/$MONGODB_DB" <<'MONGOSH' db.compositions_rps.findOne({}, { ehr_id: 1, tid: 1, time_c: 1, cn: { $slice: 3 } }) db.compositions_search.findOne({}, { ehr_id: 1, comp_id: 1, tid: 1, sort_time: 1, sn: 1 }) MONGOSH Inspect the generated Atlas Search definition cat .kehrnel/search-index.json
通过CLI扩展模式
基本流程正常运行后,继续使用CLI ,而不是直接进入自定义API连线。 CLI已经公开了主要的操作构建基块:
环境生命周期
策略激活
字典设置
搜索索引生成
查询编译
查询执行
该工具包使 kehrnel 成为策略工作的自然控制平面。单独的应用程序或用户界面可以位于其之上,但策略本身仍然是可移植的、可检查的,并且可直接通过运行时和CLI进行操作。
Continue through the CLI for strategy operations and discovery kehrnel op capabilities --env dev kehrnel op schema synthetic_generate_batch --strategy openehr.rps_dual kehrnel run rebuild_codes --env dev --domain openehr kehrnel run rebuild_shortcuts --env dev --domain openehr kehrnel run build_search_index_definition \ --env dev \ --domain openehr \ --strategy openehr.rps_dual
关键要点
将组合保留为半扁平化文档:为每个组合保留一个MongoDB文档,但将其存储为可重建的半扁平形式,而不是作为原始嵌套有效负载。
对路径进行编码和反向以实现高效匹配:将 AQL 结构路径转换为紧凑的反向词元,以便
CONTAINS可以映射到前缀友好的谓词。按范围路由 AQL:使用
ehr_id将患者范围的查询保留在本地,并在适当的时候将跨患者查询发送到Atlas Search 。根据扩展选择一两个集合:单个半扁平化集合可以很好地发挥作用,但超大型存储库会受益于较小的搜索投影。
保留一个可操作的查询界面:让应用程序团队继续使用 AQL,同时运行时处理确定性编译和执行计划。
作者
Francesc Mateu Amengual, MongoDB
Giovanni Rodriguez, MongoDB
Greg Cox, MongoDB
胡安·克罗斯利, MongoDB