了解如何使用MongoDB Atlas对 SNOMED CT 临床术语进行建模、搜索、导航和基础处理。
使用案例: 互操作性
行业: 医疗保健
产品: MongoDB Atlas、 MongoDB Search、 MongoDB Vector Search、Voyage AI
解决方案概述
医疗保健应用程序需要理解临床含义,而不仅仅是存储临床文本。医生可能会写入“心力衰竭”、“心力衰竭”或“心脏不足”。不同的词语可以描述相同的临床理念。临床编码为应用程序提供了一种标准方法,用稳定的标识符来表示该含义。
医疗保健团队出于不同目的使用不同的编码系统。某些编码系统会对诊断和遭遇群组,以用于报告、统计、报销或医院活动分析。 SNOMED CT 专注于健康记录中的临床意义。它可以代表问题、发现、程序、身体结构、有机体、物质、产品和许多其他临床想法。 SNOMED CT 支持应用程序对电子健康记录中记录的临床事实进行搜索、交换、分析或推理。
SNOMED International 将 SNOMED CT 描述为一种临床术语,其中的概念具有独特的含义、正式的定义和层次化组织。
SNOMED CT 具有类似图形的结构。临床概念的数量超过 500,000 个,每个概念都有多个人类可读的描述,包括同义词和翻译。它可以具有父概念、子概念、祖先以及与其他概念的正式关系。 SNOMED CT 通过概念、描述和关系表示术语内容,如下所示:
一个概念代表一个临床想法。
描述将人类可读的术语与该概念相关联。
关系将一个概念连接到另一个概念。
这种结构功能强大,但也带来了实施挑战。应用程序团队需要快速术语搜索、多语言查找、层次结构导航、后代扩展和关系检查。他们还需要在工作流程中使用 SNOMED 的术语,例如临床记录查看、问题列表创建、决策支持、群组发现和语义搜索。传统实施通常将这些需求分割到多个系统中:
术语文件的关系数据库。
用于文本查找的搜索引擎。
用于层次结构遍历的图表数据库。
用于语义搜索的向量数据库。
该解决方案展示了如何在MongoDB Atlas上操作 SNOMED CT,如下所示:
将每个 SNOMED 概念存储为MongoDB文档,将概念标识、描述、关系、父项、子项和祖先路径保存在一起。
为MongoDB Search 和MongoDB Vector Search 构建一个术语级搜索投影。
使用祖先数组和多键索引来支持常见的层次结构和后代查询,而无需单独的图表数据库。
使用相同的术语服务为 SNOMED 候选者提供临床记录
将审核过的编码与证据、上下文和祖先路径一起存储。
示例,用户可以搜索“心力衰竭”,检查所选的临床概念,查看其父概念和子概念,查看其形式关系,以及展开其下面的特定概念。 SNOMED CT 通常利用 ECL 来表示此类后代扩展。 ECL 用作一种紧凑查询语言,用于描述 SNOMED CT 概念集。示例,表达式 指的是“心力衰竭以及层次结构中低于其的所有概念”。在<< Heart failure MongoDB 的模式设计中,这种模式自然映射到对预先计算的祖先数组的查询。 SNOMED 的官方 ECL 参考文档将操作符<< 定义为“后代或自身”,用于检索概念及其子类型。
图 1。具有父母和孩子层次结构的临床概念
该解决方案还演示了临床笔记基础。注释可能包含当前的发现、既往病史、家族史、计划的行动、不确定的陈述和否定的发现。该应用程序提取候选临床术语,通过MongoDB搜索 SNOMED CT,提出候选概念,并仅在确认后存储已审核的编码。存储的编码保留原始证据范围、所选 SNOMED 概念、断言上下文、审阅者状态和祖先路径。然后,下游应用程序可以按临床含义(而不仅仅是确切的词语)查询。
当您需要执行以下操作时,请使用此解决方案:
搜索临床术语、同义词、翻译和 SNOMED 标识符。
浏览父视图、子视图、祖先视图、后代视图和关系视图。
支持从一个MongoDB集合中进行词法、语义和混合术语搜索。
使用 ECL 样式的层次结构表达式(例如“心力衰竭的所有后代”)扩展概念集。
通过证据跨度和人工查看为 SNOMED CT 候选对象提供基础临床记录。
将审查的 SNOMED 编码与祖先路径一起存储,以进行索引的下游查询。
这种模式为应用程序团队提供了一个操作平台,用于术语数据、术语搜索、语义检索、层次结构查询、临床证据捕获和审核的编码输出。它减少了为文档存储、搜索、语义检索和图形式导航运行单独系统的需要。
SNOMED CT 许可说明:与此解决方案关联的公共存储库仅包含一个小示例数据集。 SNOMED CT 需要适当的许可。
参考架构
该参考架构由导航和基本临床记录工作流程组成。
导航可帮助术语用户搜索、检查和确定 SNOMED CT 概念的范围。基础临床记录重复使用相同的术语检索层(默认使用确定性词法搜索)从临床文本中建议 SNOMED CT 候选,并仅存储已审核的编码。
该架构使用一设立MongoDB集合:
snomed-irbd集合存储真实来源术语视图。snomed-term-search支持高质量术语搜索。grounded_notes集合存储已审核的应用程序输出,而不是源术语数据。
SNOMED CT 内容是图表形状的。这种架构将MongoDB文档中的连接结构保持在一起,并使用搜索投影和祖先数组使它们可操作。
架构概览
此实施从授权的 SNOMED CT 内容包开始,该内容包已作为JSON概念模型提供。在当前演示中,源模型来自卫生部使用的西班牙国家 SNOMED CT 发行版。公共存储库仅包含示例数据集。它不会重新分发完整的 SNOMED CT 术语。
该架构与源格式无关。如果组织收到JSON形式的 SNOMED CT,则可以将该模型直接加载到MongoDB中。
图 2。 MongoDB作为代码权威,具有可选的、受候选限制的 LLM 网关。
目标模型具有以下术语集合:
snomed-irbd:存储每个临床概念及其描述、关系、父项、子项、祖先、活动状态、发布元数据和成员元元数据。应用程序使用此集合进行概念查找、层次结构导航、关系检查和后代扩展。snomed-term-search:为每个活动术语、语言和发布存储一个可搜索文档。应用程序使用此投影进行词法搜索、语义搜索、混合搜索、语言筛选和范围筛选。
导航API使用 snomed-term-search 来查找匹配的概念。然后,它会丰富 snomed-irbd集合中选定的结果。用户可以搜索“心力衰竭”等临床短语,检查所选概念,查看更广泛和更具体的概念,并打开同一操作的API示例。
基础API重复使用临床记录工作流程中的术语检索层。基础检索默认为确定性词法搜索,而导航提供词法、语义和混合模式。可选的 LLM层级可以帮助解释文本并在MongoDB提供的候选对象中进行选择,但它不得创建新的 SNOMED CT 标识符。
查看后,应用程序将确认的编码存储在 grounded_notes 中。每次编码都会保留所选的 SNOMED CT 概念、证据文本、断言上下文、主题上下文、审阅者状态和祖先 ID。然后,下游应用程序可以按含义(而不仅仅是确切的单词)查询已审核的临床事实。
导航工作流程
用户搜索“心力衰竭”等临床术语。应用程序查询术语搜索投影并返回按 SNOMED 概念分组的概念级结果。
每个结果均显示:
与用户查询匹配的术语
概念的首选显示
正式临床名称
SNOMED 标识符
活动状态
语义类别
发布
搜索来源
然后,用户可以打开概念焦点视图。此视图显示概念摘要、描述、父概念、子概念、关系、后代、原始文档和API示例。
导航支持以下搜索模式:
词法搜索使用MongoDB Search 来查找精确术语、同义词、正式名称、标识符、前缀和模糊文本。
语义搜索使用MongoDB Vector Search,该搜索会自动将词语的
embedText字段嵌入 voyage-4 参考模型。因此,按含义检索在同一集合上运行,无需单独的向量存储或嵌入管道。混合搜索结合了词法检索和向量检索。如果配置了 Voyage 跨编码器重排序器,则应用程序会对融合候选池进行重排序;否则,它会退回到融合顺序。
搜索屏幕还支持语义范围。用户可以将结果限制在广泛的临床领域,例如临床发现、程序、身体结构或物质。用户还可以使用后代表达式(例如 << 404684003)将结果限制为一个概念及其更具体的概念。
图 3。使用 ECL 作用域扩展语义搜索
地面临床记录工作流程
用户粘贴临床记录。工作流程提取临床提及和上下文线索,例如当前发现、否定、病史、家族史、计划的动作、不确定性和时间表达式。
然后,工作流程通过MongoDB搜索 SNOMED CT 候选。它会返回带有证据跨度和上下文的可审查候选对象。审阅者可以接受、拒绝每个候选,或将其标记为待查看。
可选的法学硕士层级可以协助文本解释和候选选择。它应该只从MongoDB返回的候选中进行选择。不得创建新的 SNOMED 标识符或查看而保留编码。
查看后,应用程序将确认的编码存储在 grounded_notes 中。每个保存的编码包括证据范围、选定的 SNOMED 概念、断言、主题、状态和祖先 ID。这种模式使下游应用程序能够查询含义。示例,应用程序可以查找包含所选临床概念的任何已接受后代的已审阅笔记。
图 4。临床记录基础 — 法学硕士 (LLM)进程
图 5。使用MongoDB进行术语搜索后,为临床记录打下基础
API代码片段示例
该解决方案为“导航”和“地面临床记录”工作流程公开了 API。这些代码片段显示了核心请求模式。
搜索 SNOMED 术语和概念
使用此端点搜索术语级投影。响应将匹配术语分组回 SNOMED 概念。它返回概念级结果,包括匹配的术语、首选显示、语义类别和搜索来源。
POST /api/navigator-search { "query": "heart failure", "languageCode": "en", "mode": "lexical", "limit": 24 }
当用户按已知术语、同义词、正式名称或 SNOMED 标识符进行搜索时,请使用词法模式。当为MongoDB Vector Search 和重新排名配置演示时, API还支持语义和混合模式。
展开概念及其后代
使用此端点扩展概念设立。 SNOMED CT 使用 ECL 来描述概念集。在此示例中,表达式<< 84114007 的意思是“心力衰竭及其以下所有更具体的概念”。
POST /api/ecl { "expr": "<< 84114007", "languageCode": "en", "limit": 200 }
该实施使用MongoDB中预先计算的祖先数组解析此表达式。这种模式可以快速实现常见的后代查询,而无需为演示架构使用单独的图表数据库。
为 SNOMED 候选者提供临床记录
使用此端点从文本中提取候选临床提及,并从MongoDB检索有界 SNOMED 候选。响应会自动生成可审核的输出,而不会自动保留代码。
POST /api/nlp-map { "text": "Patient with chronic systolic heart failure and type 2 diabetes. No evidence of chest pain at present.", "languageCode": "en" }
基础工作流程可检测临床提及和上下文,例如否定、病史、家族史、计划和时间表达式。 MongoDB提供了候选 SNOMED 概念。审核者确认最终编码。
保存审阅者确认的编码
查看后使用此端点。该应用程序仅存储已确认的编码,并使用祖先 ID 对其进行丰富,以启用下游语义查询。
POST /api/coding-confirm { "text": "Patient with heart failure.", "languageCode": "en", "codings": [ { "mention": "heart failure", "conceptId": "84114007", "displayTerm": "Heart failure", "semanticTag": "disorder", "accepted": true } ] }
保存的文档会保留选定的 SNOMED 概念、证据文本、断言上下文、审阅者状态和祖先 ID。此模式使下游查询能够按一般概念或特定后代来查找注释。
按含义查询接地笔记
使用此端点检索包含所选 SNOMED 概念或其临床派生概念的已检索笔记。
POST /api/grounded-corpus { "conceptId": "84114007", "includeDescendants": true, "limit": 10 }
该端点演示了存储祖先 ID 和已审核编码的下游价值。应用程序可以查询临床意义,而不仅仅是搜索确切的单词。
数据模型方法
SNOMED CT 表示连接的数据。临床概念可以有许多人类可读术语、几个更广泛的概念、许多更具体的概念以及与其他概念的正式关系。
MongoDB非常适合这种模式,因为大多数操作应用程序都需要以概念为中心的视图。当用户打开概念时,应用程序需要概念标识符、显示术语、描述、父项、子项、祖先路径、关系、活动状态和发布元数据。
这种方法不会删除图表结构。它存储关系并为常见导航模式添加便于查询的数组。示例,每个概念文档都可以存储其直接父文档和祖先路径。这种模式允许应用程序使用带索引的MongoDB查询查找更广泛的概念、子概念和后代。
为什么这种model有效
以下设计选择解决特定的操作要求:快速查找、准确搜索、快速层次结构遍历和可审核编码。
将概念数据放在一起:术语应用程序通常需要呈现完整的概念卡。嵌入描述、关系摘要、父 ID、子 ID 和祖先 ID,将最有用的操作视图保留在一个文档中。
将搜索与源术语分开:搜索是术语级别的,而不是概念级别的。一个概念可以有多种跨语言和方言的描述。术语级投影允许MongoDB Search 和MongoDB Vector Search 对匹配的确切术语进行排名,同时仍然返回规范概念。
预计算层次结构路径:SNOMED CT 具有丰富的层次结构。许多应用程序需要快速后代查询,例如“查找这个概念及其下面的所有更具体的概念”。存储每个概念和每个审查的临床编码的祖先 ID。然后使用多键索引进行常见的层次结构查询。
使用经过审查的编码存储证据:当应用程序可以解释其来源时,编码可以提供更大的价值。将选定的 SNOMED 概念与临床文本范围、断言状态、主题上下文和审阅者状态存储在一起。此模式支持Atlas 审核、查看和 下游 查询。
图 6。 SNOMED CT 元模型和MongoDB集合映射
SNOMED CT 元模型和MongoDB集合映射
该解决方案使用三个术语集合,以及一个单独的遥测集合。以下部分描述了文档形状以及每个文档形状的主要字段。
snomed-irbd集合
使用 snomed-irbd 作为 SNOMED CT 概念的事实来源视图。每个文档代表一个发布中的一个概念,包含其 RF2 描述、定义关系、父概念、子概念、活动状态、发布元数据以及支持层次结构和包含的预先计算的祖先闭包。
{ "conceptId": "44054006", "active": true, "effectiveTime": "20020131", "moduleId": "900000000000207008", "definitionStatusId": "900000000000074008", "descriptions": [ { "id": "73465010", "term": "Diabetes mellitus type II", "typeId": "900000000000013009", "languageCode": "en", "acceptabilityMap": { "900000000000509007": "..." } } ], "relationships": [ { "typeId": "116680003", "destinationId": "73211009", "relationshipGroup": "0", "active": "1" } ], "inferredParentIds": ["73211009"], "inferredAncestorIds": ["73211009", "64572001", "138875005"], "inferredChildIds": ["..."], "relationshipAttributeKeys": ["116680003|73211009"], "memberOfRefsetIds": ["..."], "releaseId": "20260601", "releaseDate": "2026-06-01T00:00:00.000Z", "releaseAppliedAt": "2026-07-06T00:00:00.000Z" }
snomed-irdb 包含以下相关字段:
conceptId:代表 SNOMED 标识符 (SCTID);稳定的概念标识。descriptions[]:表示概念的人类可读名称。每个名称都是同义词或完全指定的名称(正式临床名称),并记录其语言以及在该语言中是首选还是可接受的。这些条目映射到 SNOMED CT发布文件中的描述行relationships[]:表示该概念与其他概念的关系。 “Is a”关系定义了层次结构。属性关系定义了临床属性,例如查找站点或代理。relationshipAttributeKeys[]:将每个属性关系表示为单个索引值。这使应用程序可以按特定属性查找概念,并通过索引而不是完整扫描返回结果。inferredParentIds、ChildIds、AncestorIds:表示在不进行图表遍历的情况下进行包含的有界预计算闭包。使用{ inferredAncestorIds: conceptId }子句查询后代,而不是存储在每个父概念上。
sned-term-search集合测试
使用 snomed-term-search 作为搜索投影。每个文档代表一种语言和一个发布的一个活动描述术语,针对MongoDB搜索、范围筛选和自动嵌入的MongoDB Vector Search 进行了非规范化。这种结构使用户能够键入同义词、缩写词、本地化术语、正式临床名称或自然语言短语。
搜索文档重复概念上下文,使每个搜索结果自成一体。结果可以显示匹配的术语、首选显示、语义类别、活动状态、发布和层次结构范围,而无需为每个候选获取完整的概念文档。
{ "conceptId": "44054006", "descriptionId": "116680003", "term": "Type 2 diabetes mellitus", "preferredTerm": "Type 2 diabetes mellitus", "fsn": "Type 2 diabetes mellitus (disorder)", "semanticTag": "disorder", "semanticTagKey":"disorder", "termType": "synonym", "preferred": true, "languageCode": "en", "definitionStatusId": "900000000000074008", "moduleId": "900000000000207008", "effectiveTime": "20020131", "parentIds": ["73211009"], "ancestorIds": ["404684003", "73211009"], "topRoots": ["404684003"], "areaTags": ["disorder"], "releaseId": "20260601", "releaseDate": "2026-06-01T00:00:00.000Z", "embedText": "Type 2 diabetes mellitus | disorder | ..." }
snomed-term-search集合包含以下相关字段:
conceptId、descriptionId:链接回概念和具体描述。term、preferredTerm、fsn:提供匹配的术语和概念上下文,因此搜索结果是独立的。semanticTag、semanticTagKey、termType、preferred:提供过滤和排名信号。parentIds、ancestorIds、topRoots、areaTags:范围过滤器,而不连接回snomed-irbd。releaseId、releaseDate、effectiveTime:提供版本范围内的搜索和发布维护可见性。embedText:包含MongoDB自动嵌入用于向量搜索的字段。
此代码段解释了最重要的设计选择:搜索投影是术语级别的。它说明了为什么搜索“高血糖”仍然可以返回规范概念“糖尿病”
通过自动嵌入,您只需存储人类可读的 embedText字段, MongoDB Vector Search 会自动生成并维护该字段的嵌入。您不需要单独的嵌入管道或向量存储,因为语义层位于同一个集合上。
grounded_notes集合
使用 grounded_notes 来存储查看后的应用程序输出。这些文档不是源术语数据。每个文档都存储以下数据:
源文本
所选 SNOMED CT 概念
证据跨度
断言上下文,例如存在或不存在
主题上下文,例如患者或家庭成员
查看状态
祖先 ID
下面的示例展示了这种形状。
{ "tenantId": "demo-hospital", "languageCode": "en", "text": "Patient with type 2 diabetes mellitus.", "codings": [ { "conceptId": "44054006", "system": "http://snomed.info/sct", "display": "Type 2 diabetes mellitus", "semanticTag": "disorder", "role": "principal", "target": "Condition.code", "assertion": "present", "subject": "patient", "status": "accepted", "evidence": { "text": "diabetes mellitus tipo 2" }, "ancestorIds": ["44054006","75934005"] } ], "recordedAt": "2026-07-07T16:22:47.210Z", "createdAt": { "$date": "2026-07-07T16:22:47.210Z" } }
这种设计将临床文本转换为可查询的临床含义。应用程序稍后可以搜索包含 SNOMED CT 层次结构中的概念或低于该概念的任何更具体概念的已审阅笔记。每个编码都保留其证据,因此审核者可以将每个代码追溯到生成它的确切文本和上下文,这支持Atlas 审核和自信的下游使用。
遥测集合
对搜索事件、层次结构请求、笔记基础活动、反馈和诊断使用单独的 telemetry集合。将遥测数据置于概念数据模型之外。
构建解决方案
公共存储库包括应用程序代码、脚本和示例数据集。许可用户可以用自己的 SNOMED CT发布文件替换示例数据集。
先决条件
已启用MongoDB Search 的MongoDB Atlas 群集。
访问许可的 SNOMED CT发布或小示例数据集以进行演示。
用于演示应用程序的 Node.js 和npm 。
可选:用于语义搜索的MongoDB Vector Search 自动嵌入配置。
可选:Voyage 重排序键或其他为混合模式配置的重排序器。
可选:用于有界提取和候选消歧的 LLM 网关。
步骤
构建术语sidecar
从规范概念集合生成 snomed-term-search。 sidecar 为每个发布、语言、描述和概念存储一个活动术语文档。它会重复关键概念上下文,因此搜索结果无需为每个结果卡连接回概念集合。
# Curated demo branches TERM_PROJECTION_SCOPE=demo npm run terms:rebuild # Full licensed local release TERM_PROJECTION_SCOPE=full npm run terms:rebuild # Replace documents while preserving index definitions when possible npm run terms:rebuild:replace
创建MongoDB索引
创建用于概念查找和层次结构扩展的 BTree 索引。创建MongoDB Search索引以进行词汇术语查找。如果使用语义或混合模式,请为语义搜索创建MongoDB Vector Search索引。
npm run indexes:build
使用以下推荐的源集合索引:
db.getCollection("snomed-irbd").createIndex({ releaseId: 1, conceptId: 1 }) db.getCollection("snomed-irbd").createIndex({ releaseId: 1, active: 1, conceptId: 1 }) db.getCollection("snomed-irbd").createIndex({ releaseId: 1, inferredAncestorIds: 1, active: 1 })
语义搜索使用MongoDB Vector Search 自动嵌入,并将 voyage-4 作为默认模型。混合模式添加了 Voyage rerank-2.5 重新排序器。对于没有自动嵌入的集群,存在手动 Voyage 嵌入回退功能。
配置语义搜索和重新排名
语义和混合搜索使用MongoDB Vector Search 自动嵌入。使用集群上配置的嵌入模型在 embedText字段上创建向量搜索索引。
混合模式添加了可选的 Voyage 重排序器;设立VOYAGE_API_KEY 以启用它。如果没有键,混合搜索仍然有效,并回退到融合顺序。重排序器会先尝试配置的 基本URL,再尝试与 https://ai.mongodb.com/v1 } 对应的MongoDB托管的 Voyage 网关,最后是 Voyage 自己的原生平台端点。
运行演示应用程序
npm install npm run dev
使用精简的 .env.local文件。将操作默认值保留在代码或配置文件中,而不是作为一长串环境变量。
MONGODB_URI= MONGODB_DB=terminology VOYAGE_API_KEY= ENABLE_LLM_GROUNDING=false LLM_BASE_URL= LLM_API_KEY= LLM_AUTH_HEADER=api-key LLM_GROUNDING_MODEL=gpt-5.5 # Semantic / hybrid search MONGODB_VECTOR_MODE=autoEmbed MONGODB_VECTOR_INDEX=snomed_voyage_idx MONGODB_VECTOR_AUTO_EMBED_MODEL=voyage-4 VOYAGE_API_KEY= VOYAGE_RERANK_MODEL=rerank-2.5
关键要点
在MongoDB Atlas中操作 SNOMED CT:通过以文档为中心的操作模型提供图形化的临床术语,该模型支持搜索、层次结构、关系和应用程序工作流程。
统一术语导航和语义搜索:使用MongoDB Search 和MongoDB Vector Search 帮助用户从同一 Atlas 支持的服务中查找、检查和确定 SNOMED CT 概念的范围。
使用经过审核的证据来分析临床文本:使用术语服务从临床记录中提出 SNOMED CT 候选,然后存储经过审核的包含证据、上下文和祖先路径的编码。
作者
Francesc Mateu Amengual, MongoDB
Giovanni Rodríguez, MongoDB
Diego Canales, MongoDB
了解详情
MongoDB Vector Search Overview(向量搜索概述):了解MongoDB如何支持Atlas内部的语义检索和向量搜索。
获取 SNOMED CT:查看组织如何访问权限SNOMED CT 并了解其国家或地区的许可路径。
SNOMED CT 概念、描述和关系:了解此解决方案映射到MongoDB文档的基本 SNOMED CT 构建基块。