reasonhub-snomed-semantic

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SNOMED Semantic Query

SNOMED 语义查询

Overview

概述

SNOMED CT is unique among clinical terminologies: every fully-defined concept carries explicit attribute relationships encoded as FHIR properties. These let you answer questions like "all disorders of the cardiovascular system" or "all conditions with infarct morphology" using structured queries rather than keyword search.
This skill walks through the full workflow: find the pivot concept, inspect its relationships, choose the right attribute type, and build a
valueset_expand
filter that returns exactly the right set of codes.

SNOMED CT在临床术语体系中独树一帜:每个完整定义的概念都带有以FHIR属性编码的明确属性关系。借助这些关系,您无需使用关键词搜索,而是通过结构化查询就能解答诸如“所有心血管系统疾病”或“所有具有梗死形态的病症”这类问题。
本技能将引导您完成完整工作流程:找到核心概念,检查其关系,选择合适的属性类型,并构建能精准返回对应编码集的
valueset_expand
过滤器。

Output

输出

Every query produces two deliverables.
每个查询会生成两个交付成果。

1. FHIR ValueSet JSON (always deliver this)

1. FHIR ValueSet JSON(必须交付)

Return a complete
ValueSet
resource with
name
,
title
,
status
, and a populated
compose.include
. This is the primary artifact — useful whether or not expansion succeeds.
json
{
  "resourceType": "ValueSet",
  "name": "AllInfarctDisorders",
  "title": "All Infarct Disorders",
  "status": "draft",
  "compose": {
    "include": [
      {
        "system": "http://snomed.info/sct",
        "version": "<from list_available_codesystem_versions>",
        "filter": [
          { "property": "116676008", "op": "=", "value": "55641003" },
          { "property": "inactive",  "op": "=", "value": "false" }
        ]
      }
    ]
  }
}
返回包含
name
title
status
以及已填充
compose.include
的完整
ValueSet
资源。这是核心产物——无论扩展是否成功都具有实用价值。
json
{
  "resourceType": "ValueSet",
  "name": "AllInfarctDisorders",
  "title": "All Infarct Disorders",
  "status": "draft",
  "compose": {
    "include": [
      {
        "system": "http://snomed.info/sct",
        "version": "<from list_available_codesystem_versions>",
        "filter": [
          { "property": "116676008", "op": "=", "value": "55641003" },
          { "property": "inactive",  "op": "=", "value": "false" }
        ]
      }
    ]
  }
}

2. Expansion (ask the user)

2. 扩展结果(询问用户)

After delivering the ValueSet JSON, ask:
"Would you like me to expand this and show the matching codes? I can format the results as a markdown table or CSV."
If the user says yes, attempt
valueset_expand
once. On failure (see pi limitation below), explain they can run the ValueSet JSON against any FHIR terminology server or the ReasonHub API directly.
If expansion succeeds, check the response for a
total
count. The MCP transport layer truncates returned rows regardless of the
count
parameter, and
offset
-based paging is unreliable. If rows returned are fewer than
total
, label the output explicitly and stop:
⚠️ Partial result — {n} of {total} codes shown. The full set is defined by the ValueSet JSON above; run it against any FHIR terminology server for the complete expansion.
Do not retry with different
count
or
offset
values — this will not retrieve additional rows.
If expansion succeeds, use the requested format:
Markdown table (default):
CodeDisplay
22298006
Myocardial infarction
432504007
Cerebral infarction
CSV (when the user asks to download, import, or use in a spreadsheet):
csv
code,display
22298006,"Myocardial infarction"
432504007,"Cerebral infarction"
For SNOMED results, adding
semanticTag
as a third column is useful when the expansion mixes disorders, findings, and procedures:
csv
code,display,semanticTag
22298006,"Myocardial infarction",disorder
432504007,"Cerebral infarction",disorder

交付ValueSet JSON后,询问用户:
“是否需要我扩展该集合并展示匹配的编码? 我可以将结果格式化为Markdown表格CSV。”
如果用户同意,尝试执行一次
valueset_expand
。若失败(见下方pi限制说明),告知用户可将ValueSet JSON在任意FHIR术语服务器或ReasonHub API上直接运行。
若扩展成功,检查响应中的
total
计数。MCP传输层会忽略
count
参数截断返回的行数,且基于
offset
的分页不可靠。若返回行数少于
total
,需明确标记输出并停止:
⚠️ 部分结果 — 显示{total}个编码中的{n}个。完整集合由上方的ValueSet JSON定义;可在任意FHIR术语服务器上运行以获取完整扩展结果。
请勿尝试使用不同的
count
offset
值重试——这无法获取更多行数。
若扩展成功,按照用户要求的格式输出:
Markdown表格(默认):
CodeDisplay
22298006
Myocardial infarction
432504007
Cerebral infarction
CSV(当用户要求下载、导入或用于电子表格时):
csv
code,display
22298006,"Myocardial infarction"
432504007,"Cerebral infarction"
对于SNOMED结果,当扩展结果混合了疾病、症状和手术时,添加
semanticTag
作为第三列会更实用:
csv
code,display,semanticTag
22298006,"Myocardial infarction",disorder
432504007,"Cerebral infarction",disorder

SNOMED's Semantic Model

SNOMED的语义模型

Common relationship attributes

常见关系属性

This table lists frequently encountered attributes. It is not exhaustive — SNOMED CT defines hundreds of attribute types, and the exact set on any concept depends on its definition. Always use
codesystem_lookup
on a representative concept to discover the actual attributes present (see Discovering Attributes by Lookup below).
Attribute typeIdNameApplies toExample
363698007
Finding siteDisorders, findingsFinding site = Heart structure (
80891009
)
246075003
Causative agentDisorders, infectionsCausative agent = Staphylococcus (
65119002
)
116676008
Associated morphologyDisorders, findingsAssociated morphology = Infarct (
55641003
)
363704007
Procedure site - DirectProceduresThe structure directly incised/excised. Kidney biopsy uses
405813007
(Indirect) instead — look up first.
405813007
Procedure site - IndirectProceduresThe target organ reached through another structure. Often used where
363704007
might be expected.
370135005
Pathological processDisordersPathological process = Inflammatory (
441862004
)
47429007
Associated withFindings, disordersAssociated with = Hypertension (
38341003
)
42752001
Due toDisorders, findingsDue to = Type 2 diabetes mellitus (
44054006
) — links complications to causal condition
363713009
InterpretsFindingsInterprets = Blood pressure (
75367002
)
363714003
Has interpretationFindingsHas interpretation = Increased (
35105006
)
255234002
AfterProceduresAfter = General anaesthesia
下表列出了常用属性,但并非详尽无遗——SNOMED CT定义了数百种属性类型,具体概念上的属性集取决于其定义。请始终对代表性概念使用
codesystem_lookup
来发现实际存在的属性(见下文通过查询发现属性)。
属性typeId名称适用对象示例
363698007
发病部位疾病、症状发病部位 = 心脏结构 (
80891009
)
246075003
致病因子疾病、感染致病因子 = 葡萄球菌 (
65119002
)
116676008
相关形态疾病、症状相关形态 = 梗死 (
55641003
)
363704007
手术部位-直接手术直接切开/切除的结构。肾活检使用的是
405813007
(间接)——需先查询确认。
405813007
手术部位-间接手术通过其他结构到达的目标器官。常用于预期使用
363704007
的场景。
370135005
病理过程疾病病理过程 = 炎症 (
441862004
)
47429007
相关联症状、疾病相关联 = 高血压 (
38341003
)
42752001
由...引起疾病、症状由...引起 = 2型糖尿病 (
44054006
) —— 将并发症与致病病症关联
363713009
对应指标症状对应指标 = 血压 (
75367002
)
363714003
指标解读症状指标解读 = 升高 (
35105006
)
255234002
术后手术术后 = 全身麻醉

How the filter works

过滤器工作原理

Relationship filters are outbound: they find concepts where a given attribute points to a target concept.
concept --[363698007 Finding site]--> 80891009 Heart structure
So
filter: property=363698007, op==, value=80891009
returns all concepts whose "finding site" attribute equals "Heart structure".
关系过滤器是向外指向的:它们会查找指定属性指向目标概念的所有概念。
concept --[363698007 发病部位]--> 80891009 心脏结构
因此
filter: property=363698007, op==, value=80891009
会返回所有“发病部位”属性等于“心脏结构”的概念。

⚠️
=
is exact match, not subsumption

⚠️
=
是精确匹配,而非包含关系

The
=
operator matches only concepts that store exactly the specified concept ID as their attribute value. It does not apply subsumption to the value side — filtering by
363698007 = 321667001
(respiratory tract) will not automatically include concepts coded to
39607008
(lung structure) or
113255004
(lung parenchyma), even though both are subtypes of respiratory tract.
SNOMED concepts are coded to specific anatomical sites, not to tidy ancestor concepts. For example:
Concept
363698007
finding site coded to
Bacterial pneumonia (
53084003
)
113255004
Structure of parenchyma of lung
Bacterial respiratory infection (
312117008
)
20139000
Structure of respiratory system
Pneumoconiosis (
40122008
)
39607008
Lung structure
A query for
363698007 = 321667001
(respiratory tract) matches none of these, because none are coded to that exact concept ID.
Practical rule: always call
codesystem_lookup
on a few representative concepts in your target clinical domain first. Read the actual value stored for your attribute, then use that concept ID — or its closest common ancestor that concepts in that domain actually share — as your filter value.
What you cannot do directly: reverse lookups ("find all concepts that hypertension causes"). SNOMED doesn't have a
has-symptom
attribute. Use the IS-A hierarchy or causative-agent filter instead.

=
运算符仅匹配将指定概念ID作为属性值精确存储的概念。它不会对值侧应用包含关系——例如,使用
363698007 = 321667001
(呼吸道)进行过滤,不会自动包含编码为
39607008
(肺结构)或
113255004
(肺实质)的概念,即便这两者都是呼吸道的子类型。
SNOMED概念会编码至特定的解剖部位,而非通用的父类概念。例如:
概念
363698007
发病部位编码
细菌性肺炎 (
53084003
)
113255004
肺实质结构
细菌性呼吸道感染 (
312117008
)
20139000
呼吸系统结构
尘肺病 (
40122008
)
39607008
肺结构
查询
363698007 = 321667001
(呼吸道)不会匹配上述任何一个概念,因为没有概念精确编码到该ID。
实用规则: 始终先对目标临床领域中的几个代表性概念调用
codesystem_lookup
。查看属性实际存储的值,然后使用该概念ID——或该领域概念实际共享的最近公共父类ID——作为过滤值。
无法直接实现的操作: 反向查询(“查找所有由高血压引起的概念”)。SNOMED没有
has-symptom
属性。请改用IS-A层级结构或致病因子过滤器。

Workflow

工作流程

Step 1 — Identify the pivot concept

步骤1 — 确定核心概念

The pivot is the concept you want to filter by (the attribute value).
Use
search_snomed
with a descriptive query:
search_snomed(query="heart structure anatomy")
search_snomed(query="infarct morphology")
search_snomed(query="staphylococcus aureus organism")
Pick the best match. Body structures usually have semantic tag
(body structure)
, organisms have
(organism)
, morphologies have
(morphologic abnormality)
.
核心概念是您要依据其进行过滤的概念(即属性值)。
使用
search_snomed
进行描述性查询:
search_snomed(query="heart structure anatomy")
search_snomed(query="infarct morphology")
search_snomed(query="staphylococcus aureus organism")
选择最匹配的结果。身体结构通常带有语义标签
(body structure)
,生物带有
(organism)
,形态异常带有
(morphologic abnormality)

Step 2 — Confirm with
codesystem_lookup

步骤2 — 用
codesystem_lookup
确认

codesystem_lookup(code="80891009", system="http://snomed.info/sct")
Check:
  • display
    matches what you expect
  • semanticTag
    confirms the concept type
  • inactive
    is
    false
codesystem_lookup(code="80891009", system="http://snomed.info/sct")
检查:
  • display
    是否符合预期
  • semanticTag
    是否确认了概念类型
  • inactive
    是否为
    false

Step 3 — Discover the attribute type via lookup

步骤3 — 通过查询发现属性类型

Do not rely solely on the table above. Always look up a representative concept in the target domain to see which attribute typeIds are actually present:
codesystem_lookup(code="22298006", system="http://snomed.info/sct")
不要仅依赖上表。始终查询目标领域中的一个代表性概念,查看实际存在的属性typeId:
codesystem_lookup(code="22298006", system="http://snomed.info/sct")

Returns properties including:

返回的属性包括:

363698007 (Finding site) = 74281007 (Myocardium structure)

363698007 (发病部位) = 74281007 (心肌结构)

116676008 (Associated morphology) = 55641003 (Infarct)

116676008 (相关形态) = 55641003 (梗死)


Properties whose `code` is a bare numeric SNOMED ID are attribute
relationships. Named properties (`parent`, `inactive`, `semanticTag`, etc.)
are metadata, not clinical attributes.

**Example — discovering hypertension's attributes:**
codesystem_lookup(code="38341003", system="http://snomed.info/sct")

`code`为纯数字SNOMED ID的属性是关系属性。命名属性(`parent`、`inactive`、`semanticTag`等)是元数据,而非临床属性。

**示例 — 发现高血压的属性:**
codesystem_lookup(code="38341003", system="http://snomed.info/sct")

Reveals:

显示:

363698007 (Finding site) = 51840005 (Systemic circulatory system)

363698007 (发病部位) = 51840005 (全身循环系统)

363713009 (Interprets) = 35105006 (Increased)

363713009 (对应指标) = 35105006 (升高)

363714003 (Has interpretation)= 75367002 (Blood pressure)

363714003 (指标解读)= 75367002 (血压)

Note: sufficientlyDefined=false — primitive concept, sparse attributes

注意:sufficientlyDefined=false —— 基础概念,属性稀疏


Hypertension's attributes describe *what it is* (elevated BP in the
circulatory system), not its clinical associations. This is why the
`associated with` filter for "symptoms of hypertension" returns sparse
results — see [Translating Clinical Questions](#translating-clinical-questions).

高血压的属性描述的是**它是什么**(循环系统中的血压升高),而非其临床关联。这就是为什么使用`相关联`过滤器查询“高血压的症状”返回结果稀疏的原因——见[临床问题转换](#临床问题转换)。

Step 4 — Expand with a property filter

步骤4 — 使用属性过滤器扩展

json
{
  "resourceType": "ValueSet",
  "compose": {
    "include": [{
      "system": "http://snomed.info/sct",
      "version": "<use list_available_codesystem_versions>",
      "filter": [
        {
          "property": "363698007",
          "op": "=",
          "value": "80891009"
        }
      ]
    }]
  }
}
Pass this to
valueset_expand
.
⚠️ pi limitation: In the pi agent the
valueset
parameter is always received as a string due to
$ref
type serialization, causing
valueset: must be object
. Retrying or removing optional parameters will not fix this. Stop after one attempt and use
reasonhub-skills expand
instead (see
valueset-properties
skill). If the CLI is not installed (
npx skills add
does not install it), run:
curl -fsSL https://raw.githubusercontent.com/reason-healthcare/reasonhub-skills/main/bin/reasonhub-skills -o ~/.local/bin/reasonhub-skills && chmod +x ~/.local/bin/reasonhub-skills
json
{
  "resourceType": "ValueSet",
  "compose": {
    "include": [{
      "system": "http://snomed.info/sct",
      "version": "<use list_available_codesystem_versions>",
      "filter": [
        {
          "property": "363698007",
          "op": "=",
          "value": "80891009"
        }
      ]
    }]
  }
}
将此传递给
valueset_expand
⚠️ pi限制: 在pi agent中,由于
$ref
类型序列化,
valueset
参数始终以字符串形式接收,导致报错
valueset: must be object
。重试或移除可选参数无法解决此问题。尝试一次后停止,改用
reasonhub-skills expand
(见
valueset-properties
技能)。如果未安装CLI(
npx skills add
未安装),运行:
curl -fsSL https://raw.githubusercontent.com/reason-healthcare/reasonhub-skills/main/bin/reasonhub-skills -o ~/.local/bin/reasonhub-skills && chmod +x ~/.local/bin/reasonhub-skills

Step 5 — Refine with stacked filters

步骤5 — 叠加过滤器优化

Filters in the same
include
are combined with AND:
json
"filter": [
  { "property": "concept",   "op": "is-a", "value": "64572001" },
  { "property": "363698007", "op": "=",    "value": "80891009" },
  { "property": "inactive",  "op": "=",    "value": "false"    }
]
→ Active disorders (
is-a 64572001
) whose finding site is the heart.

同一
include
中的过滤器会通过AND组合:
json
"filter": [
  { "property": "concept",   "op": "is-a", "value": "64572001" },
  { "property": "363698007", "op": "=",    "value": "80891009" },
  { "property": "inactive",  "op": "=",    "value": "false"    }
]
→ 发病部位为心脏的活动性疾病(
is-a 64572001
)。

Common Clinical Patterns

常见临床模式

All disorders of a body structure

某身体结构的所有疾病

json
{ "property": "363698007", "op": "=", "value": "<body_structure_id>" }
json
{ "property": "363698007", "op": "=", "value": "<body_structure_id>" }

All disorders caused by an agent

某因子引起的所有疾病

json
{ "property": "246075003", "op": "=", "value": "<organism_or_substance_id>" }
json
{ "property": "246075003", "op": "=", "value": "<organism_or_substance_id>" }

All disorders with a morphology

具有某形态的所有疾病

json
{ "property": "116676008", "op": "=", "value": "<morphology_id>" }
json
{ "property": "116676008", "op": "=", "value": "<morphology_id>" }

All procedures on a body site

某身体部位的所有手术

json
{ "property": "363704007", "op": "=", "value": "<body_structure_id>" }
Check with
codesystem_lookup
whether the procedure uses
363704007
(Direct) or
405813007
(Indirect) — kidney biopsy, for example, uses Indirect.
json
{ "property": "363704007", "op": "=", "value": "<body_structure_id>" }
使用
codesystem_lookup
确认手术使用的是
363704007
(直接)还是
405813007
(间接)——例如肾活检使用的是间接。

All subtypes of a condition (hierarchy)

某病症的所有子类型(层级结构)

json
{ "property": "concept", "op": "is-a", "value": "<parent_concept_id>" }
⚠️
is-a
captures clinical subtypes only, NOT complications.
Concepts like "retinopathy due to T2DM" are NOT IS-A children of T2DM — they link via
42752001
(Due to). Use the two-include compose pattern below for complete eCQM sets.
json
{ "property": "concept", "op": "is-a", "value": "<parent_concept_id>" }
⚠️
is-a
仅捕获临床子类型,不包括并发症。
例如“2型糖尿病引起的视网膜病变”这类概念并非2型糖尿病的IS-A子类——它们通过
42752001
(由...引起)关联。如需完整的eCQM集合,请使用下文的双include组合模式。

Strict descendants only (exclude the parent itself)

仅严格子类(排除父类本身)

json
{ "property": "concept", "op": "descendent-of", "value": "<parent_concept_id>" }
json
{ "property": "concept", "op": "descendent-of", "value": "<parent_concept_id>" }

All disorders caused by / due to a condition

某病症引起的所有疾病

json
{ "property": "42752001", "op": "=", "value": "<condition_id>" }
Captures complication concepts encoded with "Due to" (e.g., retinopathy/neuropathy due to T2DM).
json
{ "property": "42752001", "op": "=", "value": "<condition_id>" }
捕获以“由...引起”编码的并发症概念(例如2型糖尿病引起的视网膜病变/神经病变)。

Complete eCQM ValueSet: condition subtypes + their complications (two-include compose)

完整eCQM ValueSet:病症子类型+并发症(双include组合)

json
{
  "compose": {
    "include": [
      {
        "system": "http://snomed.info/sct",
        "filter": [{ "property": "concept",  "op": "is-a", "value": "<condition_id>" }]
      },
      {
        "system": "http://snomed.info/sct",
        "filter": [{ "property": "42752001", "op": "=",   "value": "<condition_id>" }]
      }
    ]
  }
}
json
{
  "compose": {
    "include": [
      {
        "system": "http://snomed.info/sct",
        "filter": [{ "property": "concept",  "op": "is-a", "value": "<condition_id>" }]
      },
      {
        "system": "http://snomed.info/sct",
        "filter": [{ "property": "42752001", "op": "=",   "value": "<condition_id>" }]
      }
    ]
  }
}

Active concepts only (add to any filter set)

临床问题转换

json
{ "property": "inactive", "op": "=", "value": "false" }

自然语言的临床问题通常无法直接映射到单一SNOMED属性。使用下表选择最佳策略,当属性覆盖不足时使用备选方案。
临床问题最佳策略覆盖范围备选方案
“[身体部位]的所有疾病”
363698007 = <body_structure>
+
is-a 64572001
⚠️
=
是精确匹配——先查询代表性概念找到实际使用的概念ID。见下方说明。
基于身体部位疾病父类的
is-a
查询
“[因子]引起的所有病症”
246075003 = <organism/substance>
✅ 良好——感染建模完善基于感染病层级的
is-a
查询
“[身体部位]的所有手术”
363704007 = <body_structure>
+
is-a 71388002
⚠️ 先查询确认——许多手术使用
405813007
(间接)而非直接
基于手术层级的
is-a
查询
“[病症]的子类型”
concept is-a <condition>
✅ 始终有效
“与[病症]相关的症状/体征”
47429007 = <condition>
+
is-a 404684003
⚠️ 稀疏——仅返回明确编码关联的概念见下方说明
“[病症]的并发症”
42752001 = <condition>
+
is-a 64572001
✅ 良好——完整定义的并发症概念会编码此关系
47429007 = <condition>
(更宽泛的“相关联”)
“[病症]的风险因素”
47429007 = <condition>
+
is-a 229819007
⚠️ 稀疏语义搜索

Translating Clinical Questions

“相关联”模式及其局限性

Natural language clinical questions often don't map cleanly to a single SNOMED attribute. Use this table to pick the best strategy, with fallbacks when attribute coverage is thin.
Clinical questionBest strategyCoverageFallback
"All disorders of [body part]"
363698007 = <body_structure>
+
is-a 64572001
⚠️
=
is exact match — look up a representative concept first to find the actual concept ID used. See note below.
is-a
on the body-site disorder parent
"All conditions caused by [agent]"
246075003 = <organism/substance>
✅ Good — infections well-modelled
is-a
on infectious disease hierarchy
"All procedures on [body part]"
363704007 = <body_structure>
+
is-a 71388002
⚠️ Look up first — many procedures use
405813007
(Indirect) instead of Direct
is-a
on the procedure hierarchy
"Subtypes of [condition]"
concept is-a <condition>
✅ Always works
"Symptoms / findings associated with [condition]"
47429007 = <condition>
+
is-a 404684003
⚠️ Sparse — only explicitly encoded associationsSee note below
"Complications of [condition]"
42752001 = <condition>
+
is-a 64572001
✅ Good — fully-defined complication concepts encode this
47429007 = <condition>
(broader "associated with")
"Risk factors for [condition]"
47429007 = <condition>
+
is-a 229819007
⚠️ SparseSemantic search
查询“与X相关的症状/体征”的过滤器为:
json
"filter": [
  { "property": "47429007", "op": "=", "value": "<condition_id>" },
  { "property": "concept",  "op": "is-a", "value": "404684003" }
]
这仅返回将关联明确编码为向外属性的概念。覆盖范围完全取决于该病症在SNOMED中的建模完善程度:
  • 建模完善的病症(有许多完整定义的子类):返回有用结果。例如:特定传染病、代谢疾病。
  • 基础病症
    sufficientlyDefined = false
    ,如高血压):病症本身的向外属性很少,且很少有概念将高血压编码为其“相关联”值。扩展结果可能为空或非常少。
当“相关联”返回结果稀疏时,改用以下策略:
  1. 子类型——病症的子类通常就是其更具体的表现:
    json
    { "property": "concept", "op": "is-a", "value": "<condition_id>" }
  2. 发病部位——查找同一解剖部位的所有体征:
    json
    { "property": "363698007", "op": "=", "value": "<site_from_lookup>" }
    先对病症使用
    codesystem_lookup
    提取其发病部位。
  3. 语义搜索——使用
    search_snomed
    ,结合病症名称和上下文术语(如“hypertension complication”、“elevated blood pressure finding”)查找单个概念,然后构建明确列表。

The
associated with
pattern and its limits

示例:“所有梗死疾病”——发现相关形态

The filter for "symptoms/findings associated with X" is:
json
"filter": [
  { "property": "47429007", "op": "=", "value": "<condition_id>" },
  { "property": "concept",  "op": "is-a", "value": "404684003" }
]
This returns only concepts that explicitly encode the association as an outbound attribute. Coverage depends entirely on how well that condition is modelled in SNOMED:
  • Well-modelled conditions (many fully-defined descendants): returns useful results. Example: specific infectious diseases, metabolic disorders.
  • Primitive conditions (
    sufficientlyDefined = false
    , e.g., hypertension): the condition itself has few outbound attributes, and few concepts encode hypertension as their
    associated with
    value. The expansion will likely be empty or very small.
When
associated with
returns thin results, use these strategies instead:
  1. Subtypes — the condition's descendants often are its more specific presentations:
    json
    { "property": "concept", "op": "is-a", "value": "<condition_id>" }
  2. Finding site — find all findings at the same anatomical site:
    json
    { "property": "363698007", "op": "=", "value": "<site_from_lookup>" }
    Use
    codesystem_lookup
    on the condition first to extract its finding site.
  3. Semantic search — use
    search_snomed
    with the condition name plus context terms (
    "hypertension complication"
    ,
    "elevated blood pressure finding"
    ) to find individual concepts, then build an explicit list.
此示例展示了单一非层级属性过滤器如何跨所有器官系统返回临床精准、全面的结果集——这是SNOMED区别于ICD-10或文本搜索的核心能力。
undefined

Worked example: "All infarct disorders" — discovering associated morphology

步骤1 — 查询已知的完整定义梗死疾病以发现属性

This example shows how a single non-hierarchy attribute filter crosses every organ system to return a clinically precise, exhaustive result set — the capability that most distinguishes SNOMED from ICD-10 or text search.
undefined
codesystem_lookup("22298006") # 心肌梗死 → 116676008 (相关形态) = 55641003 (梗死) → 363698007 (发病部位) = 74281007 (心肌结构) → sufficientlyDefined = true ← 完整定义,属性集齐全

Step 1 — look up a known, fully-defined infarct disorder to discover the attribute

步骤2 — 确认形态概念处于激活状态且类型正确

codesystem_lookup("22298006") # Myocardial infarction → 116676008 (Associated morphology) = 55641003 (Infarct) → 363698007 (Finding site) = 74281007 (Myocardium structure) → sufficientlyDefined = true ← fully defined, complete attribute set
codesystem_lookup("55641003") # 梗死 → semanticTag = "morphologic abnormality" ← 符合116676008值的正确类型 → inactive = false

Step 2 — confirm the morphology concept is active and correctly typed

步骤3 — 验证同一形态值出现在不同器官的概念上

codesystem_lookup("55641003") # Infarct → semanticTag = "morphologic abnormality" ← correct type for 116676008 values → inactive = false
codesystem_lookup("432504007") # 脑梗死 → 116676008 (相关形态) = 55641003 (梗死) ← 相同值 → 363698007 (发病部位) = 83678007 (大脑) ← 不同部位

Step 3 — verify the same morphology value appears on a different organ

步骤4 — 确认普通中风使用的是不同形态

codesystem_lookup("432504007") # Cerebral infarction → 116676008 (Associated morphology) = 55641003 (Infarct) ← same value → 363698007 (Finding site) = 83678007 (Cerebrum) ← different site
codesystem_lookup("230690007") # 脑血管意外(中风,CVA) → 116676008 (相关形态) = 37782003 (损伤) ← 不是梗死

→ 过滤器会正确排除出血性中风和普通CVA


**步骤5 — 扩展所有器官的梗死疾病**
```json
{
  "filter": [
    { "property": "116676008", "op": "=", "value": "55641003" },
    { "property": "inactive",  "op": "=", "value": "false"    }
  ]
}
→ 心肌梗死、脑梗死、肾梗死、肺梗死、脾梗死、肠系膜梗死、骨梗死…… 一个过滤器,覆盖所有器官,无需文本匹配。
步骤6 — 仅缩小至缺血性中风(叠加过滤器)
json
{
  "filter": [
    { "property": "116676008", "op": "=", "value": "55641003" },
    { "property": "363698007", "op": "=", "value": "83678007" },
    { "property": "inactive",  "op": "=", "value": "false"    }
  ]
}
→ 脑梗死及其子类型(血栓性、栓塞性、腔隙性、桥脑梗死)——仅缺血性中风,出血性中风被主动排除。

Step 4 — confirm generic stroke uses a DIFFERENT morphology

示例实践

“所有器官的梗死疾病”

codesystem_lookup("230690007") # Cerebrovascular accident (stroke, CVA) → 116676008 (Associated morphology) = 37782003 (Damage) ← NOT Infarct

→ the filter will correctly exclude hemorrhagic stroke and generic CVA


**Step 5 — expand all infarct disorders (cross-organ)**
```json
{
  "filter": [
    { "property": "116676008", "op": "=", "value": "55641003" },
    { "property": "inactive",  "op": "=", "value": "false"    }
  ]
}
→ Myocardial infarction, cerebral infarction, renal infarction, pulmonary infarction, splenic infarction, mesenteric infarction, bone infarction… One filter. Every organ. No text matching.
Step 6 — narrow to ischemic stroke only (stacked filters)
json
{
  "filter": [
    { "property": "116676008", "op": "=", "value": "55641003" },
    { "property": "363698007", "op": "=", "value": "83678007" },
    { "property": "inactive",  "op": "=", "value": "false"    }
  ]
}
→ Cerebral infarction and its subtypes (thrombotic, embolic, lacunar, pontine) — ischemic stroke only, hemorrhagic stroke excluded by design.

  1. 查询:
    codesystem_lookup("22298006")
    116676008 = 55641003
    (形态=梗死)
  2. 验证:
    codesystem_lookup("432504007")
    → 脑梗死具有相同形态
  3. 对比:
    codesystem_lookup("230690007")
    → CVA的形态为
    37782003
    (损伤),而非梗死
  4. 过滤:
    116676008 = 55641003
    → 心肌梗死、脑梗死、肾梗死、肺梗死……
  5. 叠加:添加
    363698007 = 83678007
    (大脑)以缩小至仅缺血性中风子类型

Worked Examples

“所有心脏疾病”

"All infarct disorders across every organ"

  1. Lookup:
    codesystem_lookup("22298006")
    116676008 = 55641003
    (morphology = Infarct)
  2. Verify:
    codesystem_lookup("432504007")
    → same morphology on cerebral infarction
  3. Contrast:
    codesystem_lookup("230690007")
    → CVA has morphology =
    37782003
    (Damage), not Infarct
  4. Filter:
    116676008 = 55641003
    → MI, cerebral infarction, renal infarction, pulmonary infarction…
  5. Stack: add
    363698007 = 83678007
    (Cerebrum) to narrow to ischemic stroke subtypes only
  1. 查询:
    codesystem_lookup("22298006")
    → 确认
    363698007 = 74281007
    (心肌)——注意这是心肌而非心脏。查询多个概念以找到最常用的宽泛部位。
  2. 搜索:
    search_snomed("heart structure body structure")
    80891009
    心脏结构
  3. 过滤:在
    is-a 64572001
    (疾病)范围内使用
    363698007 = 80891009
    =
    是精确匹配。编码为
    74281007
    (心肌)或
    40527003
    (左心室)的概念会被遗漏。若覆盖不足,可使用致病因子或
    is-a
    作为更宽泛的筛选方式。

"All cardiac disorders"

“所有细菌感染”

  1. Lookup:
    codesystem_lookup("22298006")
    → confirms
    363698007 = 74281007
    (Myocardium) — note this is the myocardium, not heart. Check several concepts to find the broadest commonly-used site.
  2. Search:
    search_snomed("heart structure body structure")
    80891009
    Heart structure
  3. Filter:
    363698007 = 80891009
    inside
    is-a 64572001
    (Disorder)
    =
    is exact match. Concepts coded to
    74281007
    (Myocardium) or
    40527003
    (Left ventricle) are missed. Use causative-agent or
    is-a
    as a broader net if coverage is thin.
  1. 搜索:
    search_snomed("bacteria organism")
    409822003
    细菌
  2. 过滤:在
    is-a 40733004
    (传染病)范围内使用
    246075003 = 409822003

"All bacterial infections"

“所有缺血性病症”

  1. Search:
    search_snomed("bacteria organism")
    409822003
    Bacterium
  2. Filter:
    246075003 = 409822003
    inside
    is-a 40733004
    (Infectious disease)
  1. 搜索:
    search_snomed("ischemic process pathological")
    255426005
  2. 过滤:
    370135005 = 255426005

"All ischemic conditions"

“所有肾脏手术”

  1. Search:
    search_snomed("ischemic process pathological")
    255426005
  2. Filter:
    370135005 = 255426005
  1. 查询:
    codesystem_lookup("7246002")
    (肾活检)→
    405813007 = 64033007
    —— 使用间接部位,而非直接
  2. 搜索:
    search_snomed("kidney structure body structure")
    64033007
  3. 过滤:尝试
    363704007 = 64033007
    405813007 = 64033007
    ;两者均在
    is-a 71388002
    (手术)范围内

"All renal procedures"

eCQM分母/分子:所有2型糖尿病概念(子类型+并发症)

  1. Lookup:
    codesystem_lookup("7246002")
    (Kidney biopsy) →
    405813007 = 64033007
    — uses Indirect site, not Direct
  2. Search:
    search_snomed("kidney structure body structure")
    64033007
  3. Filter: try both
    363704007 = 64033007
    and
    405813007 = 64033007
    ; use
    is-a 71388002
    (Procedure) in both
这是构建全面eCQM标准的典型示例。
步骤1 — 验证根概念
codesystem_lookup("44054006")  →  display = "Type 2 diabetes mellitus"
                                   sufficientlyDefined = false  ← 基础概念
                                   parent = 73211009 (Diabetes mellitus)
步骤2 — 检查哪些概念是IS-A子类与并发症关联
概念编码是否属于
is-a 44054006
关联方式
肥胖型2型糖尿病
81531005
✅ 是直接
parent = 44054006
胰岛素治疗的2型糖尿病
237599002
✅ 是直接
parent = 44054006
2型糖尿病引起的视网膜病变
422034002
❌ 否
42752001
(由...引起) =
44054006
2型糖尿病引起的神经病变
368581000119106
❌ 否
42752001
(由...引起) =
44054006
2型糖尿病引起的冠心病
16891151000119103
❌ 否
42752001
(由...引起) =
44054006
仅使用
is-a
会遗漏所有并发症概念。如需完整的eCQM集合,请使用合并两个树结构的双include ValueSet。
步骤3 — 构建完整ValueSet
json
{
  "resourceType": "ValueSet",
  "compose": {
    "include": [
      {
        "system": "http://snomed.info/sct",
        "version": "<see list_available_codesystem_versions>",
        "filter": [
          { "property": "concept", "op": "is-a", "value": "44054006" },
          { "property": "inactive", "op": "=",   "value": "false" }
        ]
      },
      {
        "system": "http://snomed.info/sct",
        "version": "<see list_available_codesystem_versions>",
        "filter": [
          { "property": "42752001", "op": "=",   "value": "44054006" },
          { "property": "inactive", "op": "=",   "value": "false" }
        ]
      }
    ]
  }
}
  • Include 1 捕获根编码
    44054006
    及其所有IS-A子类型(2型糖尿病的临床变体)
  • Include 2 捕获所有以“由2型糖尿病引起”编码的并发症(视网膜病变、神经病变、肾病、外周血管疾病等)
  • 两者共同构成大多数eCQM所需的完整分母或分子集合
范围说明: 如果指标明确排除根编码(在预协调IG中少见但可能),请在include 1中使用
descendent-of
替代
is-a

eCQM denominator/numerator: all T2DM concepts (subtypes + complications)

通过查询发现属性

This is the canonical example for building exhaustive eCQM criteria.
Step 1 — Verify the root concept
codesystem_lookup("44054006")  →  display = "Type 2 diabetes mellitus"
                                   sufficientlyDefined = false  ← primitive
                                   parent = 73211009 (Diabetes mellitus)
Step 2 — Check which concepts are IS-A children vs. complication-linked
ConceptCodeIn
is-a 44054006
?
Link
T2DM in obese
81531005
✅ Yesdirect
parent = 44054006
Insulin-treated T2DM
237599002
✅ Yesdirect
parent = 44054006
Retinopathy due to T2DM
422034002
❌ No
42752001
(Due to) =
44054006
Neuropathy due to T2DM
368581000119106
❌ No
42752001
(Due to) =
44054006
CAD due to T2DM
16891151000119103
❌ No
42752001
(Due to) =
44054006
is-a
alone misses all complication concepts. For a complete eCQM set, use a two-include ValueSet that unions both trees.
Step 3 — Build the complete ValueSet
json
{
  "resourceType": "ValueSet",
  "compose": {
    "include": [
      {
        "system": "http://snomed.info/sct",
        "version": "<see list_available_codesystem_versions>",
        "filter": [
          { "property": "concept", "op": "is-a", "value": "44054006" },
          { "property": "inactive", "op": "=",   "value": "false" }
        ]
      },
      {
        "system": "http://snomed.info/sct",
        "version": "<see list_available_codesystem_versions>",
        "filter": [
          { "property": "42752001", "op": "=",   "value": "44054006" },
          { "property": "inactive", "op": "=",   "value": "false" }
        ]
      }
    ]
  }
}
  • Include 1 captures the root code
    44054006
    plus all IS-A subtypes (clinical variants of T2DM)
  • Include 2 captures all complications encoded with "Due to = T2DM" (retinopathy, neuropathy, nephropathy, peripheral vascular disease, etc.)
  • Together they form the exhaustive denominator or numerator set most eCQMs require
Scope note: use
descendent-of
instead of
is-a
in include 1 if the measure exclicitly excludes the root code (uncommon but possible in pre-coordinated IGs).

前文的属性表只是起点,而非完整列表。权威来源是概念数据本身。
流程:
  1. 从目标临床领域中选择一个知名的、完整定义的(
    sufficientlyDefined = true
    )示例概念。
  2. 对其调用
    codesystem_lookup
  3. 在响应中,找到
    code
    为纯数字SNOMED概念ID的
    property
    条目——这些是关系属性。
  4. description
    字段是属性的名称(例如
    "Myocardium structure"
    )。要获取属性类型名称,请对typeId本身调用
    codesystem_lookup
    (例如
    codesystem_lookup("363698007")
    "Finding site"
    )。
  5. valueset_expand
    过滤器中使用这些typeId。
优先选择完整定义的概念进行发现。 基础概念(
sufficientlyDefined = false
)的关系属性较少或没有,无法揭示其临床类别使用的完整属性集。
undefined

Discovering Attributes by Lookup

优质发现目标:心肌梗死(sufficientlyDefined=true)

The attribute table earlier is a starting point, not a complete list. The authoritative source is the concept data itself.
Protocol:
  1. Pick a well-known, fully-defined (
    sufficientlyDefined = true
    ) example concept from the target clinical domain.
  2. Call
    codesystem_lookup
    on it.
  3. In the response, find
    property
    entries whose
    code
    is a bare numeric SNOMED concept ID — those are attribute relationships.
  4. The
    description
    field names the attribute (e.g.,
    "Myocardium structure"
    ). To get the attribute type name, call
    codesystem_lookup
    on the typeId itself (e.g.,
    codesystem_lookup("363698007")
    "Finding site"
    ).
  5. Use those typeIds in your
    valueset_expand
    filter.
Prefer fully-defined concepts for discovery. Primitive concepts (
sufficientlyDefined = false
) have fewer or no attribute relationships and will not reveal the full attribute set used by their clinical class.
undefined
codesystem_lookup("22298006") → 363698007、116676008存在

Good discovery target: Myocardial infarction (sufficientlyDefined=true)

劣质发现目标:高血压疾病(sufficientlyDefined=false)

codesystem_lookup("22298006") → 363698007, 116676008 present
codesystem_lookup("38341003") → 仅存在363698007、363713009、363714003 (疾病属性的不完整呈现)

---

Poor discovery target: Hypertensive disorder (sufficientlyDefined=false)

层级检查

codesystem_lookup("38341003") → only 363698007, 363713009, 363714003 (incomplete picture of disorder attributes)

---
构建层级过滤器前,验证关系:
codesystem_subsumes(
  code_a="64572001",   # 疾病
  code_b="22298006",   # 心肌梗死
  system="http://snomed.info/sct"
)

Hierarchy Checks

预期结果:subsumed-by(心肌梗死是疾病的子类型)

Before building a hierarchy filter, verify the relationship:
codesystem_subsumes(
  code_a="64572001",   # Disease
  code_b="22298006",   # Myocardial infarction
  system="http://snomed.info/sct"
)

---

Expected: subsumed-by (MI is a subtype of Disease)

获取完整属性参考


---
codesystem_filter_properties(system="http://snomed.info/sct")

Getting the Full Property Reference

重要限制

codesystem_filter_properties(system="http://snomed.info/sct")

  • 仅存储激活状态的关系。已停用概念的属性会被排除。
  • 基础概念
    sufficientlyDefined = false
    )可能没有或只有少量关系属性——它们仅通过IS-A定义。
  • 导入时会扁平化关系角色组。单个角色组内的组合属性(例如“发病部位+相关形态”)在过滤器中不会被强制组合。
  • SNOMED中不存在
    has-symptom
    属性。请使用临床问题转换部分的推荐策略,包括“相关联”过滤器、发病部位核心查询和层级遍历。

Important Constraints

  • Only active relationships are stored. Inactive concept attributes are excluded.
  • Primitive concepts (
    sufficientlyDefined = false
    ) may have no or fewer attribute relationships — they're defined only by IS-A.
  • Relationship role groups are flattened during import. Combined attributes within a single role group (e.g., "finding site + associated morphology") are not enforced together in filters.
  • No
    has-symptom
    attribute exists in SNOMED. Use the Translating Clinical Questions section for the recommended strategies, including
    associated with
    filters, finding-site pivots, and hierarchy traversal.