You've already forked DataMate
核心功能: - 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
14 KiB
14 KiB
DataMate 知识图谱架构设计
🏗️ 整体架构
分层架构
┌─────────────────────────────────────────────────────────────┐
│ 前端层 (Frontend) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ React + AntV G6 │ │
│ │ - 图谱可视化(分层加载、子图裁剪) │ │
│ │ - 图谱编辑(Human-in-the-loop) │ │
│ │ - 查询界面(Cypher 查询构建器) │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓ HTTP/REST
┌─────────────────────────────────────────────────────────────┐
│ 服务层 (Service) │
│ ┌──────────────────────┐ ┌──────────────────────────┐ │
│ │ kg-service │ │ rag-query-service │ │
│ │ (Spring Boot) │ │ (FastAPI) │ │
│ │ │ │ │ │
│ │ - 图查询 API │ │ - 混合检索 │ │
│ │ - 权限过滤 │ │ - GraphRAG │ │
│ │ - 缓存层 (Redis) │ │ - 向量检索 + 图检索 │ │
│ └──────────────────────┘ └──────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 摄入层 (Ingestion) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ kg-ingestion (FastAPI) │ │
│ │ - LangChain LLMGraphTransformer │ │
│ │ - 实体对齐(向量相似度 + LLM) │ │
│ │ - 关系生成(规则 + LLM) │ │
│ │ - 置信度评分 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 存储层 (Storage) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ MySQL │ │ Neo4j │ │ Milvus │ │
│ │ (元数据) │ │ (图结构) │ │ (向量) │ │
│ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────┘
🔧 技术选型
图数据库:Neo4j
选择理由:
- ✅ 成熟稳定,社区活跃
- ✅ Cypher 查询语言简洁强大
- ✅ Spring Data Neo4j 集成良好
- ✅ 支持 ACID 事务
- ✅ 丰富的图算法库
版本:Neo4j 社区版(生产环境可升级企业版)
配置:
- 端口:7474 (HTTP), 7687 (Bolt)
- 内存:heap 512MB, page cache 512MB(可根据数据量调整)
- 持久化:Docker volume
后端框架
knowledge-graph-service (Spring Boot)
职责:
- 图谱查询 API
- 权限控制和租户隔离
- 缓存管理
- 与其他服务集成
技术栈:
- Spring Boot 3.x
- Spring Data Neo4j
- Spring Security(权限控制)
- Redis(缓存)
DDD 分层:
com.datamate.knowledgegraph/
├── application/ # 应用服务层
│ └── GraphEntityService.java
├── domain/ # 领域层
│ ├── model/
│ │ ├── GraphEntity.java
│ │ └── GraphRelation.java
│ └── repository/
│ └── GraphEntityRepository.java
├── infrastructure/ # 基础设施层
│ ├── neo4j/
│ │ └── KnowledgeGraphProperties.java
│ └── exception/
│ └── KnowledgeGraphErrorCode.java
└── interfaces/ # 接口层
├── rest/
│ └── GraphEntityController.java
└── dto/
├── CreateEntityRequest.java
├── UpdateEntityRequest.java
└── CreateRelationRequest.java
kg-ingestion (FastAPI)
职责:
- 知识抽取(文本 → 实体 + 关系)
- 实体对齐和消歧
- 关系生成和验证
- 置信度评分
技术栈:
- FastAPI
- LangChain
- LangChain LLMGraphTransformer
- Pydantic(数据验证)
模块结构:
kg_extraction/
├── __init__.py
├── models.py # 数据模型
├── extractor.py # 抽取器
└── aligner.py # 实体对齐(待实现)
前端框架
技术栈:
- React 18
- AntV G6(图可视化)
- TypeScript
- Ant Design(UI 组件)
核心功能:
- 图谱可视化(支持 10000+ 节点)
- 交互式查询构建器
- 实时编辑和反馈
- 导出和分享
🔐 安全设计
多租户隔离
策略:
- 所有实体和关系都包含
graph_id属性 - 查询时自动添加
graph_id过滤条件 - Neo4j 索引包含
graph_id
实现:
// 创建索引
CREATE INDEX entity_graph_id IF NOT EXISTS FOR (n:Entity) ON (n.graph_id);
// 查询时自动过滤
MATCH (n:Entity {graph_id: $graphId})
WHERE n.id = $entityId
RETURN n;
权限控制
graphId 双重防御:
- Controller 层:
@Pattern(regexp = UUID_REGEX)格式校验 - Service 层:
validateGraphId()业务校验
实现:
// Controller 层
@GetMapping("/{graphId}/entities/{entityId}")
public GraphEntity getEntity(
@PathVariable @Pattern(regexp = UUID_REGEX) String graphId,
@PathVariable @Pattern(regexp = UUID_REGEX) String entityId
) {
return entityService.getEntity(graphId, entityId);
}
// Service 层
public GraphEntity getEntity(String graphId, String entityId) {
validateGraphId(graphId);
return entityRepository.findByIdAndGraphId(entityId, graphId)
.orElseThrow(() -> BusinessException.of(
KnowledgeGraphErrorCode.ENTITY_NOT_FOUND
));
}
Cypher 注入防护
策略:
- 使用参数化查询
- 禁止拼接 Cypher 字符串
- 输入验证和转义
示例:
// ✅ 正确:参数化查询
@Query("MATCH (n:Entity {id: $id, graph_id: $graphId}) RETURN n")
Optional<GraphEntity> findByIdAndGraphId(
@Param("id") String id,
@Param("graphId") String graphId
);
// ❌ 错误:字符串拼接
String cypher = "MATCH (n:Entity {id: '" + id + "'}) RETURN n";
📊 数据同步策略
MySQL → Neo4j 同步
策略:最终一致性 + 对账机制
同步方式:
- 实时同步:通过 CDC(Change Data Capture)捕获 MySQL 变更
- 批量同步:定时任务(每小时/每天)全量同步
- 手动同步:提供 API 触发同步
对账机制:
- 每天凌晨对比 MySQL 和 Neo4j 的数据
- 发现不一致时记录日志并告警
- 提供修复工具
实现:
@Scheduled(cron = "0 0 * * * *") // 每小时
public void syncFromMySQL() {
// 1. 查询 MySQL 中的变更
List<Dataset> changedDatasets = datasetRepository
.findByUpdatedAtAfter(lastSyncTime);
// 2. 转换为图实体
List<GraphEntity> entities = changedDatasets.stream()
.map(this::toGraphEntity)
.collect(Collectors.toList());
// 3. 批量写入 Neo4j
graphEntityRepository.saveAll(entities);
// 4. 更新同步时间
lastSyncTime = Instant.now();
}
⚡ 性能优化
查询优化
策略:
- 限制遍历深度:最大 3 跳
- 限制返回节点数:最大 1000 个
- 使用索引:在高频查询字段上创建索引
- 缓存热点数据:使用 Redis 缓存
实现:
public List<GraphEntity> getNeighbors(
String graphId,
String entityId,
int depth,
int limit
) {
// Clamp 参数
int actualDepth = Math.min(depth, properties.getMaxDepth());
int actualLimit = Math.min(limit, properties.getMaxNodesPerQuery());
// 查询
return entityRepository.findNeighbors(
graphId, entityId, actualDepth, actualLimit
);
}
索引策略
必需索引:
// 实体 ID 索引
CREATE INDEX entity_id IF NOT EXISTS FOR (n:Entity) ON (n.id);
// 图 ID 索引
CREATE INDEX entity_graph_id IF NOT EXISTS FOR (n:Entity) ON (n.graph_id);
// 复合索引
CREATE INDEX entity_id_graph_id IF NOT EXISTS
FOR (n:Entity) ON (n.id, n.graph_id);
缓存策略
缓存层次:
- L1 缓存:Spring Cache(本地缓存)
- L2 缓存:Redis(分布式缓存)
- L3 缓存:Neo4j 内置缓存
缓存内容:
- 热点实体(访问频率 > 100/小时)
- 常用子图(2-hop 邻居)
- 查询结果(TTL 5 分钟)
🔄 GraphRAG 融合
混合检索架构
用户查询
↓
┌─────────────────────────────────────┐
│ 查询理解和改写 │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ 并行检索 │
│ ┌───────────┐ ┌─────────────┐ │
│ │ Milvus │ │ Neo4j │ │
│ │ 向量检索 │ │ 图检索 │ │
│ │ Top-K │ │ 2-hop 子图 │ │
│ └───────────┘ └─────────────┘ │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ 结果融合和排序 │
│ - 向量相似度 × 0.6 │
│ - 图结构相关性 × 0.4 │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Context 构建 │
│ - 文档片段(Milvus) │
│ - 三元组文本化(Neo4j) │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ LLM 生成 │
└─────────────────────────────────────┘
三元组文本化
策略:将图结构转换为自然语言
示例:
# 图结构
(Dataset:用户行为数据)-[HAS_FIELD]->(Field:user_id)
(Dataset:用户行为数据)-[USED_BY]->(Workflow:用户画像构建)
# 文本化
"""
数据集"用户行为数据"包含字段"user_id"。
数据集"用户行为数据"被工作流"用户画像构建"使用。
"""
📈 监控和运维
监控指标
Neo4j 指标:
- 节点数量
- 关系数量
- 查询响应时间
- 内存使用率
- 磁盘使用率
服务指标:
- API 响应时间
- 错误率
- 吞吐量
- 缓存命中率
工具:
- Prometheus(指标采集)
- Grafana(可视化)
- Neo4j Metrics(Neo4j 专用指标)
备份策略
Neo4j 备份:
- 每天凌晨全量备份
- 保留最近 7 天的备份
- 备份到对象存储(S3/OSS)
恢复测试:
- 每月进行一次恢复演练
- 验证备份的完整性和可用性