Files
DataMate/docs/knowledge-graph/schema/relationships.md
Jerry Yan afcb8783aa feat(kg): 实现 Phase 3.1 前端图谱浏览器
核心功能:
- G6 v5 力导向图,支持交互式缩放、平移、拖拽
- 5 种布局模式:force, circular, grid, radial, concentric
- 双击展开节点邻居到图中(增量探索)
- 全文搜索,类型过滤,结果高亮(变暗/高亮状态)
- 节点详情抽屉:实体属性、别名、置信度、关系列表(可导航)
- 关系详情抽屉:类型、源/目标、权重、置信度、属性
- 查询构建器:最短路径/全路径查询,可配置 maxDepth/maxPaths
- 基于 UUID 的图加载(输入或 URL 参数 ?graphId=...)
- 大图性能优化(200 节点阈值,超过时禁用动画)

新增文件(13 个):
- knowledge-graph.model.ts - TypeScript 接口,匹配 Java DTOs
- knowledge-graph.api.ts - API 服务,包含所有 KG REST 端点
- knowledge-graph.const.ts - 实体类型颜色、关系类型标签、中文显示名称
- graphTransform.ts - 后端数据 → G6 节点/边格式转换 + 合并工具
- graphConfig.ts - G6 v5 图配置(节点/边样式、行为、布局)
- hooks/useGraphData.ts - 数据钩子:加载子图、展开节点、搜索、合并
- hooks/useGraphLayout.ts - 布局钩子:5 种布局类型
- components/GraphCanvas.tsx - G6 v5 画布,力导向布局,缩放/平移/拖拽
- components/SearchPanel.tsx - 全文实体搜索,类型过滤
- components/NodeDetail.tsx - 实体详情抽屉
- components/RelationDetail.tsx - 关系详情抽屉
- components/QueryBuilder.tsx - 路径查询构建器
- Home/KnowledgeGraphPage.tsx - 主页面,整合所有组件

修改文件(5 个):
- package.json - 添加 @antv/g6 v5 依赖
- vite.config.ts - 添加 /knowledge-graph 代理规则
- auth/permissions.ts - 添加 knowledgeGraphRead/knowledgeGraphWrite
- pages/Layout/menu.tsx - 添加知识图谱菜单项(Network 图标)
- routes/routes.ts - 添加 /data/knowledge-graph 路由

新增文档(10 个):
- docs/knowledge-graph/ - 完整的知识图谱设计文档

Bug 修复(Codex 审查后修复):
- P1: 详情抽屉状态与选中状态不一致(显示旧数据)
- P1: 查询构建器未实现(最短路径/多路径查询)
- P2: 实体类型映射 Organization → Org(匹配后端)
- P2: getSubgraph depth 参数无效(改用正确端点)
- P2: AllPathsVO 字段名不一致(totalPaths → pathCount)
- P2: 搜索取消逻辑无效(传递 AbortController.signal)
- P2: 大图性能优化(动画降级)
- P3: 移除未使用的类型导入

构建验证:
- tsc --noEmit  clean
- eslint  0 errors/warnings
- vite build  successful
2026-02-20 19:13:46 +08:00

18 KiB

DataMate 知识图谱 - 核心关系定义

Schema 版本:1.0.0 更新日期:2026-02-17

概述

DataMate 知识图谱定义了 10 类核心关系,覆盖数据血缘、任务编排、组织归属和知识溯源四大场景。

所有关系在 Neo4j 中统一使用 RELATED_TO 关系类型,通过 relation_type 属性区分语义类型。每个关系都包含以下公共属性:

公共属性 类型 必填 说明
id String (UUID) 关系唯一标识符
relation_type String 语义关系类型(见下文各类型定义)
graph_id String (UUID) 所属图谱 ID
weight Double 关系权重 0.0-1.0(默认 1.0)
confidence Double 置信度 0.0-1.0(同步数据默认 1.0,抽取数据由模型评分)
source_id String 来源记录 ID
properties_json String 扩展属性 JSON
created_at LocalDateTime 创建时间

关系方向约定

所有关系均为有向关系。方向表示语义上的"主动方 → 被动方"关系:

  • (A)-[:RELATED_TO {relation_type: 'HAS_FIELD'}]->(B) 表示 A 拥有 B
  • 查询时应注意方向,反向查询需要使用 <-[]- 语法

1. HAS_FIELD(包含字段)

方向Dataset → Field

表示数据集包含某个字段/列。这是数据血缘分析的基础关系,支撑字段级影响评估。

关系属性

属性 类型 必填 说明
ordinal Integer 字段在数据集中的位置(从 0 开始)
required Boolean 是否为必填字段

约束

  • 源实体类型必须为 Dataset
  • 目标实体类型必须为 Field
  • 同一 Dataset → Field 对不应重复

Cypher 示例

// 创建 HAS_FIELD 关系
MATCH (d:Entity {id: $datasetId, graph_id: $graphId})
MATCH (f:Entity {id: $fieldId, graph_id: $graphId})
CREATE (d)-[r:RELATED_TO {
  id: randomUUID(),
  relation_type: 'HAS_FIELD',
  graph_id: $graphId,
  weight: 1.0,
  confidence: 1.0,
  source_id: '',
  properties_json: '{"ordinal": 0, "required": true}',
  created_at: datetime()
}]->(f)

// 查询数据集的所有字段
MATCH (d:Entity {id: $datasetId, graph_id: $graphId})
      -[r:RELATED_TO {relation_type: 'HAS_FIELD', graph_id: $graphId}]->
      (f:Entity {graph_id: $graphId})
RETURN f ORDER BY r.properties_json

业务场景

  • 查看数据集包含哪些字段
  • 字段搜索:找到包含 user_id 字段的所有数据集
  • Schema 对比:比较两个数据集的字段差异

2. DERIVED_FROM(派生自)

方向Dataset → Dataset

表示数据集之间的血缘关系:目标数据集是源数据集经过某种处理后派生出来的。涵盖数据清洗、数据合成、版本迭代等场景。

关系属性

属性 类型 必填 说明
derivation_type String 派生类型:CLEANING(清洗)/ SYNTHESIS(合成)/ SPLIT(拆分)/ MERGE(合并)/ VERSION(版本迭代)
job_id String 产生该派生关系的作业 ID
transformation String 转换描述(如"去重 + 格式标准化")

约束

  • 源实体和目标实体类型均为 Dataset
  • 不允许自引用(源 ≠ 目标)
  • 建议检查避免循环依赖

Cypher 示例

// 创建清洗派生关系
MATCH (output:Entity {id: $outputDatasetId, graph_id: $graphId})
MATCH (input:Entity {id: $inputDatasetId, graph_id: $graphId})
CREATE (output)-[r:RELATED_TO {
  id: randomUUID(),
  relation_type: 'DERIVED_FROM',
  graph_id: $graphId,
  weight: 1.0,
  confidence: 1.0,
  properties_json: '{"derivation_type":"CLEANING","job_id":"d3e4f5a6-...","transformation":"SimHash去重 + 空值过滤"}',
  created_at: datetime()
}]->(input)

// 追踪数据血缘(最多 5 跳)
MATCH path = (d:Entity {id: $datasetId, graph_id: $graphId})
             -[:RELATED_TO *1..5 {relation_type: 'DERIVED_FROM'}]->
             (ancestor:Entity {graph_id: $graphId})
RETURN path

业务场景

  • 数据血缘追踪:追溯数据集的来源链路
  • 影响分析:当源数据集变更时,哪些下游数据集受影响
  • 版本管理:查看数据集的版本演进历史

3. USES_DATASET(使用数据集)

方向Job | LabelTask | Workflow → Dataset

表示作业、标注任务或工作流使用某个数据集作为输入。

关系属性

属性 类型 必填 说明
usage_role String 使用角色:INPUT(输入)/ REFERENCE(参考)/ VALIDATION(验证)

约束

  • 源实体类型为 JobLabelTaskWorkflow
  • 目标实体类型为 Dataset

Cypher 示例

// 创建使用关系
MATCH (j:Entity {id: $jobId, graph_id: $graphId})
MATCH (d:Entity {id: $datasetId, graph_id: $graphId})
CREATE (j)-[r:RELATED_TO {
  id: randomUUID(),
  relation_type: 'USES_DATASET',
  graph_id: $graphId,
  weight: 1.0,
  confidence: 1.0,
  properties_json: '{"usage_role":"INPUT"}',
  created_at: datetime()
}]->(d)

// 查询数据集被哪些作业使用
MATCH (j:Entity {graph_id: $graphId})
      -[r:RELATED_TO {relation_type: 'USES_DATASET', graph_id: $graphId}]->
      (d:Entity {id: $datasetId, graph_id: $graphId})
RETURN j

业务场景

  • 查看数据集的消费者:谁在使用这个数据集
  • 评估数据集的重要程度:被多少任务依赖
  • 任务输入追溯:任务使用了哪些数据集

4. PRODUCES(产出)

方向Job → Dataset

表示作业执行后产出了一个新的数据集。与 USES_DATASET 相对,构成完整的输入输出链路。

关系属性

属性 类型 必填 说明
output_type String 产出类型:PRIMARY(主输出)/ SECONDARY(副产物,如日志、统计报告)

约束

  • 源实体类型为 Job
  • 目标实体类型为 Dataset
  • 一个 Job 可以产出多个 Dataset(如主输出 + 统计报告)

Cypher 示例

// 创建产出关系
MATCH (j:Entity {id: $jobId, graph_id: $graphId})
MATCH (d:Entity {id: $outputDatasetId, graph_id: $graphId})
CREATE (j)-[r:RELATED_TO {
  id: randomUUID(),
  relation_type: 'PRODUCES',
  graph_id: $graphId,
  weight: 1.0,
  confidence: 1.0,
  properties_json: '{"output_type":"PRIMARY"}',
  created_at: datetime()
}]->(d)

// 查看作业的完整输入输出
MATCH (input:Entity {graph_id: $graphId})
      <-[:RELATED_TO {relation_type: 'USES_DATASET'}]-
      (j:Entity {id: $jobId, graph_id: $graphId})
      -[:RELATED_TO {relation_type: 'PRODUCES'}]->
      (output:Entity {graph_id: $graphId})
RETURN input, j, output

业务场景

  • 端到端血缘:结合 USES_DATASET 查看 Input → Job → Output 完整链路
  • 产出追踪:查看作业产出了哪些数据集
  • 成本归因:将产出数据集的成本归因到执行作业

5. ASSIGNED_TO(分配给)

方向LabelTask | Job → User

表示任务被分配给某个用户执行。

关系属性

属性 类型 必填 说明
assigned_at String 分配时间(ISO 8601)
role String 分配角色:EXECUTOR(执行者)/ REVIEWER(审核者)/ OWNER(负责人)

约束

  • 源实体类型为 LabelTaskJob
  • 目标实体类型为 User
  • 同一任务可分配给多个用户(不同角色)

Cypher 示例

// 创建分配关系
MATCH (t:Entity {id: $taskId, graph_id: $graphId})
MATCH (u:Entity {id: $userId, graph_id: $graphId})
CREATE (t)-[r:RELATED_TO {
  id: randomUUID(),
  relation_type: 'ASSIGNED_TO',
  graph_id: $graphId,
  weight: 1.0,
  confidence: 1.0,
  properties_json: '{"assigned_at":"2026-02-15T10:00:00","role":"EXECUTOR"}',
  created_at: datetime()
}]->(u)

// 查询用户的所有待办任务
MATCH (t:Entity {graph_id: $graphId})
      -[r:RELATED_TO {relation_type: 'ASSIGNED_TO', graph_id: $graphId}]->
      (u:Entity {id: $userId, graph_id: $graphId})
RETURN t

业务场景

  • 工作量分析:查看用户被分配了多少任务
  • 任务追踪:查看任务的执行者和审核者
  • 人员负载均衡:分析团队内任务分配情况

6. BELONGS_TO(归属于)

方向User → OrgDataset → Org

表示用户属于某个组织,或数据集归属于某个组织。

关系属性

属性 类型 必填 说明
membership_type String 归属类型:PRIMARY(主归属)/ SECONDARY(兼任/共享)
since String 归属起始时间(ISO 8601)

约束

  • 源实体类型为 UserDataset
  • 目标实体类型为 Org
  • User → Org 通常为 1:1(主归属),但允许兼任

Cypher 示例

// 用户归属组织
MATCH (u:Entity {id: $userId, graph_id: $graphId})
MATCH (o:Entity {id: $orgId, graph_id: $graphId})
CREATE (u)-[r:RELATED_TO {
  id: randomUUID(),
  relation_type: 'BELONGS_TO',
  graph_id: $graphId,
  weight: 1.0,
  confidence: 1.0,
  properties_json: '{"membership_type":"PRIMARY","since":"2025-03-01T00:00:00"}',
  created_at: datetime()
}]->(o)

// 查询组织下的所有数据资产
MATCH (d:Entity {type: 'Dataset', graph_id: $graphId})
      -[:RELATED_TO {relation_type: 'BELONGS_TO', graph_id: $graphId}]->
      (o:Entity {id: $orgId, graph_id: $graphId})
RETURN d

业务场景

  • 组织资产看板:查看组织拥有的所有数据集
  • 权限继承:基于组织关系推导数据访问权限
  • 跨组织协作:发现共享数据集的组织关系

7. TRIGGERS(触发)

方向Workflow → Job

表示工作流触发了一次作业执行。

关系属性

属性 类型 必填 说明
trigger_type String 触发方式:MANUAL(手动)/ SCHEDULED(定时)/ EVENT(事件驱动)
triggered_at String 触发时间(ISO 8601)

约束

  • 源实体类型为 Workflow
  • 目标实体类型为 Job
  • 一个 Workflow 可触发多个 Job(每次执行产生一个)

Cypher 示例

// 创建触发关系
MATCH (w:Entity {id: $workflowId, graph_id: $graphId})
MATCH (j:Entity {id: $jobId, graph_id: $graphId})
CREATE (w)-[r:RELATED_TO {
  id: randomUUID(),
  relation_type: 'TRIGGERS',
  graph_id: $graphId,
  weight: 1.0,
  confidence: 1.0,
  properties_json: '{"trigger_type":"SCHEDULED","triggered_at":"2026-02-15T10:00:00"}',
  created_at: datetime()
}]->(j)

// 查询工作流的执行历史
MATCH (w:Entity {id: $workflowId, graph_id: $graphId})
      -[r:RELATED_TO {relation_type: 'TRIGGERS', graph_id: $graphId}]->
      (j:Entity {graph_id: $graphId})
RETURN j ORDER BY r.created_at DESC

业务场景

  • 执行历史:查看工作流的所有执行记录
  • 故障排查:定位工作流最近一次失败的作业
  • 运行统计:统计工作流的执行频率和成功率

8. DEPENDS_ON(依赖)

方向Job → Job

表示作业之间的执行依赖关系:源作业的执行依赖于目标作业的完成。

关系属性

属性 类型 必填 说明
dependency_type String 依赖类型:STRICT(强依赖,必须成功)/ SOFT(弱依赖,失败可继续)

约束

  • 源实体和目标实体类型均为 Job
  • 不允许自引用
  • 不允许循环依赖(应用层校验)

Cypher 示例

// 创建依赖关系
MATCH (j1:Entity {id: $jobId, graph_id: $graphId})
MATCH (j2:Entity {id: $dependsOnJobId, graph_id: $graphId})
CREATE (j1)-[r:RELATED_TO {
  id: randomUUID(),
  relation_type: 'DEPENDS_ON',
  graph_id: $graphId,
  weight: 1.0,
  confidence: 1.0,
  properties_json: '{"dependency_type":"STRICT"}',
  created_at: datetime()
}]->(j2)

// 查询作业的完整依赖链
MATCH path = (j:Entity {id: $jobId, graph_id: $graphId})
             -[:RELATED_TO *1..10 {relation_type: 'DEPENDS_ON'}]->
             (dep:Entity {graph_id: $graphId})
RETURN path

业务场景

  • DAG 执行调度:确定作业执行顺序
  • 失败传播分析:当某个作业失败,哪些下游作业受影响
  • 关键路径分析:找到最长依赖链,识别瓶颈

9. IMPACTS(影响)

方向Field → Field

表示字段之间的影响关系:源字段的变更会影响目标字段。这是跨数据集的字段级血缘关系。

关系属性

属性 类型 必填 说明
impact_type String 影响类型:DIRECT(直接映射)/ TRANSFORM(转换派生)/ AGGREGATE(聚合计算)
transformation_rule String 转换规则描述(如"UPPER(source.name)")
job_id String 建立该影响关系的作业 ID

约束

  • 源实体和目标实体类型均为 Field
  • 通常跨越不同 Dataset(但同 Dataset 内的字段派生也允许)
  • 不允许自引用

Cypher 示例

// 创建字段影响关系
MATCH (f1:Entity {id: $sourceFieldId, graph_id: $graphId})
MATCH (f2:Entity {id: $targetFieldId, graph_id: $graphId})
CREATE (f1)-[r:RELATED_TO {
  id: randomUUID(),
  relation_type: 'IMPACTS',
  graph_id: $graphId,
  weight: 0.8,
  confidence: 0.9,
  properties_json: '{"impact_type":"TRANSFORM","transformation_rule":"TRIM(LOWER(source))","job_id":"d3e4f5a6-..."}',
  created_at: datetime()
}]->(f2)

// 查询字段的影响范围(下游)
MATCH (f:Entity {id: $fieldId, graph_id: $graphId})
      -[:RELATED_TO *1..5 {relation_type: 'IMPACTS'}]->
      (downstream:Entity {graph_id: $graphId})
RETURN downstream

业务场景

  • 字段级血缘:追踪字段从源到目标的完整链路
  • 影响评估:修改某个字段前,评估下游影响范围
  • 数据质量追溯:发现下游字段质量问题时,回溯源头

10. SOURCED_FROM(来源于)

方向KnowledgeSet → Dataset

表示知识集的知识内容来源于某个数据集,是知识溯源的基础关系。

关系属性

属性 类型 必填 说明
extraction_method String 抽取方式:LLM(LLM 抽取)/ RULE(规则抽取)/ MANUAL(人工整理)
extracted_at String 抽取时间(ISO 8601)
item_count Integer 从该数据集抽取的知识条目数

约束

  • 源实体类型为 KnowledgeSet
  • 目标实体类型为 Dataset
  • 一个 KnowledgeSet 可来源于多个 Dataset

Cypher 示例

// 创建来源关系
MATCH (k:Entity {id: $knowledgeSetId, graph_id: $graphId})
MATCH (d:Entity {id: $datasetId, graph_id: $graphId})
CREATE (k)-[r:RELATED_TO {
  id: randomUUID(),
  relation_type: 'SOURCED_FROM',
  graph_id: $graphId,
  weight: 1.0,
  confidence: 0.85,
  properties_json: '{"extraction_method":"LLM","extracted_at":"2026-02-10T14:30:00","item_count":120}',
  created_at: datetime()
}]->(d)

// 查询知识集的所有数据来源
MATCH (k:Entity {id: $knowledgeSetId, graph_id: $graphId})
      -[r:RELATED_TO {relation_type: 'SOURCED_FROM', graph_id: $graphId}]->
      (d:Entity {graph_id: $graphId})
RETURN d, r.properties_json AS extraction_info

业务场景

  • 知识溯源:查看知识集基于哪些数据构建
  • 数据变更通知:当源数据集更新时,提醒知识集需要刷新
  • 知识覆盖分析:查看哪些数据集尚未被纳入知识管理

关系类型汇总

关系类型 方向 relation_type 值 核心用途
HAS_FIELD Dataset → Field HAS_FIELD 数据集字段结构
DERIVED_FROM Dataset → Dataset DERIVED_FROM 数据集级血缘
USES_DATASET Job/LabelTask/Workflow → Dataset USES_DATASET 输入依赖
PRODUCES Job → Dataset PRODUCES 输出产出
ASSIGNED_TO LabelTask/Job → User ASSIGNED_TO 任务分配
BELONGS_TO User/Dataset → Org BELONGS_TO 组织归属
TRIGGERS Workflow → Job TRIGGERS 流程触发
DEPENDS_ON Job → Job DEPENDS_ON 作业依赖
IMPACTS Field → Field IMPACTS 字段级血缘
SOURCED_FROM KnowledgeSet → Dataset SOURCED_FROM 知识溯源

典型查询模式

1. 端到端数据血缘

// 从最终数据集追溯到原始数据集,经过的所有处理步骤
MATCH path = (final:Entity {id: $datasetId, graph_id: $graphId})
             -[:RELATED_TO *1..10]->
             (origin:Entity {graph_id: $graphId})
WHERE ALL(r IN relationships(path) WHERE r.relation_type IN ['DERIVED_FROM', 'USES_DATASET', 'PRODUCES'])
RETURN path

2. 数据集影响分析

// 查找修改某数据集后,所有受影响的下游实体
MATCH (d:Entity {id: $datasetId, graph_id: $graphId})
      <-[:RELATED_TO {relation_type: 'USES_DATASET'}]-
      (consumer:Entity {graph_id: $graphId})
RETURN consumer.type AS entity_type, consumer.name AS entity_name, consumer.id AS entity_id

3. 用户工作看板

// 查询用户相关的所有实体和关系
MATCH (u:Entity {id: $userId, type: 'User', graph_id: $graphId})
OPTIONAL MATCH (task:Entity)-[:RELATED_TO {relation_type: 'ASSIGNED_TO'}]->(u)
OPTIONAL MATCH (u)-[:RELATED_TO {relation_type: 'BELONGS_TO'}]->(org:Entity)
RETURN u, collect(DISTINCT task) AS tasks, collect(DISTINCT org) AS orgs

扩展说明

  • 自定义关系类型:除上述 10 类核心关系外,用户可通过 LLM 抽取或手动创建自定义关系类型。自定义关系使用相同的 RELATED_TO Neo4j 关系类型和公共属性结构,relation_type 字段可为任意字符串。
  • 双向关系:所有关系均为单向。如果需要表达双向关系(如"A 和 B 互相影响"),应创建两条方向相反的关系。
  • 关系去重:应用层应在创建关系前检查是否已存在相同的(source, target, relation_type)组合,避免重复。