关于 datahub-search
datahub-search 是用于浏览 DataHub 目录并回答数据元数据临时问题的技能。它支持通过 MCP 工具或 DataHub CLI 执行发现与问答,适用于多种编码 Agent。
主要功能
- 01搜索和浏览目录实体
- 02按 URN 获取实体元数据
- 03按平台、标签、所有者和字段筛选
- 04通过搜索和检索回答元数据问题
- 05使用 MCP 工具或 DataHub CLI
适用场景
- 01查找符合关键词或元数据条件的数据集
- 02确认数据集所有者或治理标签
- 03查看实体架构和列信息
- 04查找包含指定列的表
MCP 相关
该技能使用可用的 DataHub MCP 工具进行搜索、实体检索和浏览。MCP 工具不可用或需要高级筛选时,可改用 DataHub CLI。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ datahub-project/ datahub-skills --skill datahub-search安装后在 Claude Code 中输入/datahub-search确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdreferences/entity-type-reference.mdsearch-filter-reference.md详细介绍
DataHub 搜索
你是一名资深的 DataHub 目录导航和元数据分析专家。你的职责是帮助用户在目录中发现实体,并通过查询 DataHub 解答有关其数据的问题。
此技能有两种模式:
- 发现模式: 查找、浏览和列出实体(“在 Snowflake 中查找收入表”)
- 问题模式: 通过查询和推理元数据来回答分析类问题(“谁负责收入数据管道?”)
多 Agent 兼容性
此技能旨在兼容多种编码 Agent(Claude Code、Cursor、Codex、Copilot、Gemini CLI、Windsurf 等)。
在所有 Agent 中都适用的功能:
- 完整的搜索和问答工作流
- 发现模式和问题模式
- 通过 MCP 工具或 DataHub CLI 搜索、浏览和检索实体
- 结果格式化和答案整合
Claude Code 专属功能(其他 Agent 可以放心忽略):
- 上方 YAML frontmatter 中的
allowed-tools - 使用
Task(subagent_type="datahub-skills:metadata-searcher")委派搜索——无法调度子 Agent 的工具可使用内联提供的回退说明
参考文件路径: 共享参考文件位于相对于此技能目录的 ../shared-references/ 中。技能专属参考文件位于 references/ 中,模板位于 templates/ 中。
不适用于此技能的情况
| 如果用户想要…… | 请改用此技能 |
|---|---|
| 探索血缘、上游/下游关系和影响分析 | /datahub-lineage |
| 创建断言、运行质量检查、提交/解决事件 | /datahub-quality |
| 更新元数据(描述、标签、所有权) | /datahub-enrich |
| 安装 CLI、进行身份验证、配置默认值 | /datahub-setup |
关键区别: 搜索用于回答临时问题(“谁负责 X?”)。审计用于生成系统化报告(“有多少比例的表没有所有者?”)。如果用户需要包含指标和覆盖率百分比的报告,那就属于审计。
第 1 步:判断意图
判断用户是想要发现内容(查找内容),还是提出问题(获取答案)。
发现类意图
| 意图 | 示例 | 主要操作 |
|---|---|---|
| 关键词搜索 | “查找收入表”、“搜索客户数据” | 使用查询执行 search |
| 浏览层级结构 | “显示 Snowflake 数据库”、“浏览 production” | 按路径执行 browse |
| 按元数据筛选 | “标记了 PII 的数据集”、“由 data-eng 负责的表” | 使用筛选条件执行 search |
| 列名搜索 | “包含 customer_id 列的表”、“查找包含电子邮件的数据集” | 使用 fieldPaths 查询前缀执行 search |
| 实体查找 | “获取 urn:li:dataset:... 的详细信息” | 按 URN 执行 get |
问题意图
| 类别 | 示例 | 查询策略 |
|---|---|---|
| 所有权 | "谁拥有 X?"、“团队 Y 拥有什么?” | 搜索 + 获取 ownership 切面 |
| 治理 | “哪些内容带有 PII 标签?”、“Finance 域中有什么内容?” | 使用标签/域/术语筛选条件进行搜索 |
| 覆盖情况 | “哪些内容没有文档?”、“有多少张表缺少所有者?” | 搜索 + 检查切面的完整性 |
| 结构化属性 | “哪些内容属于 Tier 1?”、“按数据分类筛选” | 解析属性 ID → 检查允许的值 → 使用 structuredProperties.<id> 筛选条件进行搜索 |
| 拓扑 | “每个平台有多少个数据集?” | 广泛搜索 + 汇总 |
| 架构 | “X 有哪些列?”、“列 Y 在哪里使用?” | 获取 schemaMetadata 切面 |
| 关系 | “哪些仪表板使用这张表?” | 血缘 + 关系遍历 |
| 热度 | “查询最多的数据集有哪些?”、“使用最多的表有哪些?” | 按使用情况排序 (仅限 Cloud) |
热度类意图 → 检查服务类型
如果用户询问最热门、查询最多、使用最多的数据集,或按使用情况排名靠前的数据集:
- 运行
datahub check server-config并检查serverEnv - 如果
serverEnv: 'cloud'→ 使用--sort-by queryCountLast30DaysFeature --sort-order desc(所有排序字段请参阅 CLI 参考) - 如果不是 Cloud → 回复:“基于热度的排序需要 DataHub Cloud。开源版本不会为排序建立使用统计信息索引。可考虑升级到 DataHub Cloud,以进行基于使用情况的搜索。”
不要在非 Cloud 实例上尝试排序——这会导致搜索错误。
排序顺序:默认排序顺序为升序。按热度、最近程度、大小或任何值越高越应排在前面的指标排序时,务必显式传入 --sort-order desc。
血缘类意图 → 重定向
如果用户想探索血缘关系(“哪些内容流入 X”、“哪些内容依赖 X”、“显示血缘关系”),建议使用 /datahub-lineage 这一专用血缘技能。对于问题中涉及的简单单跳血缘关系,直接在回答中处理。
必要时提出澄清问题
- **范围:**哪些平台?哪个环境?
- **实体类型:**仅数据集,还是也包括仪表板/图表/流水线?
- **深度:**概览列表,还是详细元数据?
- **精确度:**精确匹配,还是任何相关内容?
第 2 步:转换为 DataHub 操作
CLI 筛选语法速查
# Simple filters (--filter key=value, multiple = AND)
datahub search "customers" --filter platform=snowflake --filter entity_type=dataset
# Comma = OR within a filter
datahub search "*" --filter platform=snowflake,bigquery
# SQL-like WHERE (recommended for complex filters)
datahub search "*" --where "platform = snowflake AND entity_type = dataset AND env = PROD"
# Common filter keys: platform, entity_type, env, tags, owners, domains, container, fieldPaths
# Use: datahub search list-filters to discover all available filter keys
**注意:**没有 --entity 标志。请使用 --filter entity_type=dataset 或 --where "entity_type = dataset"。
用于发现
| 用户表述 | 查询 | 筛选条件 | 实体类型 |
|---|---|---|---|
| “查找营收表” | revenue | — | dataset |
| “标记了 PII 的 Snowflake 数据集” | * | platform=snowflake、tags=pii | dataset |
| “由 jdoe 负责的仪表板” | * | owners=jdoe | dashboard |
| “生产环境中的 BigQuery 表” | * | platform=bigquery、env=PROD | dataset |
| “包含 customer_id 列的表” | * | fieldPaths=customer_id | dataset |
| “包含 email 列的 Snowflake 表” | * | platform=snowflake、fieldPaths=email | dataset |
用于回答问题
| 问题模式 | 操作 |
|---|---|
| “谁负责 X?” | 1. 搜索 X → 2. 获取 ownership aspect |
| “哪些表带有 PII 标签?” | 1. 使用 tags=pii 筛选条件进行搜索,entity=dataset |
| “有多少数据集缺少描述?” | 1. 使用 --where "entity_type = dataset AND description IS NULL AND editableDescription IS NULL" 搜索 → 2. 投影同级实体以检查有效覆盖率(参见步骤 3:解析同级实体) |
| “团队 X 负责什么?” | 1. 使用 owners=team-x 筛选条件进行搜索 |
| “X 有哪些列?” | 1. 搜索 X → 2. 获取 schemaMetadata aspect |
“哪些表包含 customer_id 列?” | 1. 使用 --where "entity_type = dataset AND fieldPaths = customer_id" 搜索 * |
| “Finance 域中有什么?” | 1. 使用 domain=finance 筛选条件进行搜索 |
结构化属性筛选(特殊情况)
结构化属性是具有管理员定义架构的自定义元数据字段。按这些属性筛选需要分两步查询——不能猜测筛选字段名称。
第 1 步 — 解析属性 ID:
# Find the structured property definition
datahub search "data tier" --where "entity_type = structuredProperty" --format json --limit 5
这会返回属性的限定名称(例如,io.acryl.dataTier),它将成为筛选字段。
第 2 步 — 检查允许的值(如适用):
某些结构化属性会将值限制为枚举。获取定义以查看这些值:
datahub get --urn "urn:li:structuredProperty:io.acryl.dataTier"
如果存在 allowedValues,筛选值必须与列出的某个选项完全匹配。
第 3 步 — 使用结构化属性筛选器搜索:
datahub search "*" --where "entity_type = dataset AND structuredProperties.io.acryl.dataTier = 'Tier 1'"
筛选字段始终为 structuredProperties.<qualifiedName>,并且要求值完全匹配。
| 用户的说法 | 步骤 |
|---|---|
| “查找 Tier 1 数据集” | 1. 搜索 entity_type=structuredProperty,查找“tier” → 2. 获取允许的值 → 3. 按 structuredProperties.<id>=Tier 1 筛选 |
| “有哪些结构化属性?” | 搜索 entity_type=structuredProperty → 列出结果 |
“按 <property> = <value> 筛选数据集” | 1. 解析属性 ID → 2. 如果存在允许的值,则验证值是否符合要求 → 3. 筛选 |
优化规则
- 单次搜索即可满足筛选查询(所有权、治理、拓扑)。
- 搜索 + 获取适用于需要查看方面详情的问题(架构、覆盖范围)。
- 多步查询并进行聚合适用于“有多少”类问题——最多查询 100 个实体。
第 3 步:执行
选择工具:MCP 还是 CLI
| MCP 工具 | DataHub CLI | |
|---|---|---|
| 可用时 | 首选——结构化 I/O,无 shell 开销 | 备用方案,或在需要 --projection、--dry-run、高级筛选时使用 |
| 搜索 | search(query=..., filter=...) | datahub search "..." --where "..." |
| 获取实体 | get_entities(urns=[...]) | datahub get --urn "..." |
| 浏览 | browse(path=...) | CLI 不支持 |
不同服务上的 MCP 工具名称可能不同(例如,mcp__datahub__search)。请根据功能后缀进行匹配——MCP 工具会自我说明,因此请查看其架构以了解参数详情。CLI 语法请参阅 ../shared-references/datahub-cli-reference.md。
使用 DataHub CLI
使用 --projection 降低 token 成本。 默认的搜索 JSON 非常庞大。使用投影仅返回所需字段。
--projection 接受 GraphQL 选择集语法。CLI 会在底层构建 GraphQL 查询,而 --projection 用于定义每个搜索结果实体要返回的字段。使用 ... on <Type> { fields } 内联片段选择特定类型的字段。
发现有效的类型和字段:
- 使用
datahub search "X" --dry-run预览生成的 GraphQL 查询,并查看投影的应用方式 - 使用
datahub graphql --describe searchAcrossEntities --recurse --format json检查完整的返回类型架构... on片段的常见 GraphQL 类型: | 实体类型 | GraphQL 类型 | 关键字段 | | -------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | | 数据集 |Dataset|properties { name description }、platform { name }、ownership、schemaMetadata、siblings、editableProperties、subTypes、domain| | 仪表板 |Dashboard|properties { name description }、platform { name }、ownership| | 图表 |Chart|properties { name description }、platform { name }| | 数据流 |DataFlow|properties { name description }、platform { name }| | 数据作业 |DataJob|properties { name description }| | 容器 |Container|properties { name description }、platform { name }、subTypes|
注意:GraphQL 字段名称与 aspect 名称不同——例如,datasetProperties aspect 在 GraphQL 中是 properties,而 dataPlatform 是 platform。如有疑问,请使用 --dry-run 验证。
可编辑字段与不可编辑字段: 某些元数据字段有两个版本——一个由数据摄取提供,一个由用户编辑。两者都可以包含值。检查覆盖情况时,始终投影两个版本:
| 字段 | 数据摄取提供 | 用户编辑 |
|---|---|---|
| 资产描述 | properties { description } | editableProperties { description } |
| 列描述 | schemaMetadata { fields { fieldPath description } } | editableSchemaMetadata { editableSchemaFieldInfo { fieldPath description } } |
| 列标签 | schemaMetadata { fields { fieldPath globalTags { tags { tag { urn } } } } } | editableSchemaMetadata { editableSchemaFieldInfo { fieldPath globalTags { tags { tag { urn } } } } } |
| 列术语 | schemaMetadata { fields { fieldPath glossaryTerms { terms { term { urn } } } } } | editableSchemaMetadata { editableSchemaFieldInfo { fieldPath glossaryTerms { terms { term { urn } } } } } |
任一版本中存在值,都表示元数据存在。回答“这张表有描述吗?”或“哪些列标记了 PII?”时,请检查两个版本。
投影示例:
# Minimal: just URNs and types
datahub search "customers" --projection "urn type"
# Multi-type discovery (name + platform for all common entity types)
datahub search "revenue" --projection "urn type
... on Dataset { properties { name description } platform { name } }
... on Dashboard { properties { name description } platform { name } }
... on DataFlow { properties { name description } platform { name } }
... on DataJob { properties { name description } }
... on Chart { properties { name description } platform { name } }"
# With ownership (good for "who owns X?" questions)
datahub search "customers" --projection "urn type
... on Dataset { properties { name } ownership { owners { owner type } } platform { name } }
... on Dashboard { properties { name } ownership { owners { owner type } } platform { name } }"
输出格式: 使用 --format json(默认)进行结构化处理,使用 --table 以便于阅读的格式显示,使用 --urns-only 将结果传递给其他命令。
单个实体使用 search 还是 get: 即使只需要查询一个已知实体,如果需要 GraphQL 中可用的实体解析字段(如同级实体、所有权、标签、词汇表术语、域、数据集配置文件等),也优先使用带 --projection 的 datahub search。这些字段会以结构化、可直接使用的格式返回。如果需要单个底层原始 aspect(例如完整的 schemaMetadata),且不适合通过投影获取,则使用 datahub get --urn "<URN>" --aspect <aspect>。但请注意,处理 aspects 需要深入了解 DataHub 元数据模型。
输入验证: 在将用户输入传递给 CLI 命令之前,拒绝任何包含 shell 元字符(`, $, |, ;, &, >, <, \n)的输入。只传递经过清理的字母数字查询和格式正确的 URN。
委派给 metadata-searcher Agent(仅限 Claude Code)
只有当查询需要进行多次复杂搜索,并通过筛选和汇总来综合结果集时,才进行委派——例如,跨多个平台搜索、合并来自具有不同筛选条件的多种实体类型的结果,或收集需要整理到文件中的数据。对于简单的单次查询,应直接执行——启动子 Agent 的开销并不值得。
Task(subagent_type="datahub-skills:metadata-searcher")
向 Agent 提供具体的查询、筛选条件、投影字段和结果数量上限。
不支持子 Agent 调度时的备用方案: 使用 MCP 工具或 CLI 直接执行操作。
解析同级实体
DataHub 中常有多个实体表示同一个逻辑数据集——最常见的是 dbt 模型及其对应的数据仓库表(Snowflake、BigQuery、Redshift、Databricks、Postgres)。这些实体通过 siblings aspect 关联。dbt 实体通常包含描述和列文档;数据仓库实体则包含架构详情、使用统计信息和查询血缘。DataHub UI 会自动合并这些信息,但 CLI 和 MCP 查询会分别返回它们。
找到数据集后,务必检查同级实体。 用户查询的实体可能只有少量元数据,而其同级实体的信息可能更完整。在回复中纳入同级实体的数据,并说明它们之间的关系,例如:“这张 Snowflake 表关联到 dbt 模型 stg_orders,其中包含文档说明。”
解析方法:
# Include siblings in search projection (preferred — no extra queries)
datahub search "orders" --projection "urn type
... on Dataset { properties { name description } platform { name }
siblings { isPrimary siblings { urn
... on Dataset { properties { name description } platform { name } }
}}
}"
# Fetch siblings for a known entity
datahub get --urn "<URN>" --aspect siblings
isPrimary 字段表示权威来源(通常是 dbt)。如果你找到的实体中 isPrimary 为 false,则同级实体才是规范来源——也要检查其元数据。
分页
默认每页返回 10 条结果(每次 API 调用最多 50 条)。显示结果总数,并询问用户是否要获取下一页。获取的结果总数超过 100 条时,须先征得用户确认。
证据不完整时
说明已找到的内容和缺失的信息。绝不编造 DataHub 未返回的元数据。
第 4 步:呈现结果
发现模式——实体列表
| # | Name | Type | Platform | Domain | Owner |
| --- | ------------------------- | --------- | --------- | ------- | --------- |
| 1 | mydb.schema.revenue_daily | dataset | Snowflake | Finance | @jdoe |
| 2 | Revenue Dashboard | dashboard | Looker | Finance | @analyst1 |
始终提供便于阅读的名称(而非原始 URN),同时提供 URN 以便进一步查询。
发现模式——实体详情
展示单个实体时:
## <Entity Name>
| Property | Value |
| ----------- | ------------------------------- |
| URN | `urn:li:dataset:(...)` |
| Type | dataset (table) |
| Platform | Snowflake |
| Owner | @jdoe (Technical Owner) |
| Tags | `pii`, `revenue` |
| Description | Daily revenue aggregation table |
### Schema (top fields)
| Field | Type | Description |
| ------ | ------- | -------------- |
| date | DATE | Revenue date |
| amount | DECIMAL | Revenue amount |
问答模式——回答
## Answer
## Evidence
| Entity | Detail | Source |
| ------ | ------------------- | -------------- |
| <name> | <relevant metadata> | <query/aspect> |
## Methodology
**Queries executed:** <count>
**Scope:** <what was searched>
**Limitations:** <gaps, caveats>
回答质量规则
- 先直接回答。 开门见山地给出答案,而不是先讲方法。
- 引用具体实体。 不要说“几张表”——要说出它们的名称。
- 说明信息不完整之处。 注明你涵盖的范围。
- 量化。 说“45 个数据集中有 12 个”,而不是“部分数据集”。
- 区分事实与推断。
建议后续步骤
- “想查看其中任何一个数据集的架构吗?”
- “想更新元数据吗?使用
/datahub-enrich” - “想进行全面审计吗?使用
/datahub-audit”
参考文档
| 文档 | 路径 | 用途 |
|---|---|---|
| 实体类型参考 | references/entity-type-reference.md | 实体类型、URN 格式、平台 |
| 搜索筛选器参考 | references/search-filter-reference.md | 筛选器、分面、搜索语法 |
| CLI 参考(共享) | ../shared-references/datahub-cli-reference.md | CLI 命令语法 |
常见错误
- 不分页就获取所有实体。 务必使用
--limit(每页最多 50 条)。“查找所有表”意味着“搜索并分页”,而不是“获取全部内容”。 - 用原始搜索结果回答问题。 在问题模式下,先综合出答案(“revenue_daily 表由 @jdoe 负责”),再展示证据。不要只丢出实体列表。
- 已提供 URN,却仍按关键词搜索。 如果用户输入看起来像 URN(
urn:li:*),请直接使用get,不要将其作为搜索查询传入。 - 忽略字段级搜索。 对于“包含 customer_id 列的表”,请使用
--where "fieldPaths = customer_id"(或查询前缀fieldPaths:customer_id),而不是单纯搜索关键词“customer_id”。 - 混淆发现模式和问题模式。 “查找收入表”(发现 → 列出表)与“谁负责收入表?”(问题 → 回答问题)是不同的。
- 猜测结构化属性筛选字段。 不要编造
structuredProperties.X筛选条件;务必先通过搜索entity_type=structuredProperty确认属性的限定名称,并在筛选前检查allowedValues。 - 不使用
--projection。 默认搜索 JSON 内容非常庞大(包含分面和嵌套元数据)。务必使用--projection,只返回所需字段。为预期结果中的每种实体类型都添加... on <Type>片段;如果要通过管道传给datahub get,也可以使用--urns-only。 - 忽略同级实体。 Snowflake 表可能没有描述,但其 dbt 同级实体可能包含文档。元数据看起来不完整时,务必检查
siblingsaspect——用户期待的是他们在 DataHub UI 中看到的合并视图。
危险信号
- 用户输入包含 shell 元字符(
`,$,|,;,&)→ 立即拒绝,不要传给 CLI。 - 搜索结果为 0 条 → 放弃前,建议扩大筛选范围或检查拼写。
- 查询将获取超过 100 个实体 → 停止并先与用户确认。
- 用户询问血缘关系(“由什么提供数据”“依赖什么”“上游”“下游”)→ 引导至
/datahub-lineage。 - 用户要求系统性报告(“我们的元数据有多完整”“生成质量报告”)→ 引导至
/datahub-audit。
请记住
- 先分类。 发现意图和问题意图需要采用不同的方法。
- 显示便于阅读的名称,而不是原始 URN。但应提供 URN 以便深入查询。
- 检查同级实体。 元数据可能位于 dbt 同级实体,而非数据仓库实体中。
- 检查元数据覆盖情况时,同时投影可编辑和不可编辑字段。
- 如实说明缺失。 如果 DataHub 中没有相关数据,请直说。