-
Notifications
You must be signed in to change notification settings - Fork 407
Open
Labels
bugSomething isn't workingSomething isn't working
Description
图谱数据不一致性问题:边引用了不存在的节点
问题描述
在查询图谱子图 API 时,返回的数据中包含引用了不存在节点的边。这导致前端图谱可视化失败,出现 "Node not found" 错误。
环境信息
- 后端: FastAPI + LightRAG
- 前端: Vue.js + @antv/g6
- 图谱类型: LightRAG 知识图谱
- 数据库 ID:
kb_ab5c6bfdefb044c7ad08e8cc0f2da3a8
复现步骤
-
调用子图 API,使用以下参数:
GET /api/graph/subgraph?db_id=kb_ab5c6bfdefb044c7ad08e8cc0f2da3a8&node_label=GB+20071-2025&max_depth=2&max_nodes=50 -
检查响应数据:
data.nodes: 包含 50 个节点的数组data.edges: 包含 139 条边的数组
-
检查数据一致性:
- 某些边引用了不存在于节点数组中的节点 ID
- 示例:边 ID
2752引用了目标节点"耻骨结合点力的峰值(PSPF)",但该节点不在节点数组中
问题数据示例
引用不存在节点的边:
{
"id": "2752",
"source_id": "WorldSID 50th假人",
"target_id": "耻骨结合点力的峰值(PSPF)",
"type": "related",
"properties": {
"file_path": "http://localhost:9000/ref-kb-ab5c6bfdefb044c7ad08e8cc0f2da3a8/GBT 37337-2019 _1766122855408.pdf",
"keywords": "传感器测量,性能指标",
"weight": 1.0,
"description": "耻骨结合点力的峰值是WorldSID 50th假人的骨盆性能指标,由骨盆载荷传感器测量。"
}
}节点验证:
# 查询返回空结果 - 节点在响应中不存在
curl -s "http://localhost:5050/api/graph/subgraph?..." | jq '.data.nodes[] | select(.id == "耻骨结合点力的峰值(PSPF)")'
# 输出: (空)前端错误
当 G6 尝试渲染图谱时,抛出错误:
Uncaught Error: Node not found for id: 耻骨结合点力的峰值(PSPF)
at _Graph.getNode (graph.ts:296:13)
at _Graph.checkNodeExistence (graph.ts:268:10)
at _Graph.doAddEdge (graph.ts:577:10)
根本原因分析
问题出现在后端子图查询逻辑中:
- API 将返回的节点数量限制为
max_nodes=50 - 但是,边是基于这些节点的关系收集的
- 某些边可能引用了由于节点限制而被排除的节点
- 这造成了边引用结果集外节点的不一致性
期望行为
API 应该返回一致的数据,其中:
- 所有边只引用
nodes数组中存在的节点 - 或者 API 应该包含所有被返回边引用的节点(即使超过
max_nodes) - 或者 API 应该过滤掉引用结果集外节点的边
临时解决方案(前端)
已在前端实现临时修复,过滤掉无效的边:
// In web/src/components/GraphCanvas.vue - formatData()
const nodeIds = new Set()
for (const n of data.nodes) {
nodeIds.add(String(n.id))
}
// Filter out edges with missing nodes
const validEdges = (data.edges || []).filter((e) => {
const sourceExists = nodeIds.has(String(e.source_id))
const targetExists = nodeIds.has(String(e.target_id))
if (!sourceExists || !targetExists) {
console.warn('Filtering out edge with missing nodes:', {
edge: e.id,
source: e.source_id,
target: e.target_id
})
return false
}
return true
})建议修复方案(后端)
后端子图查询应该修改以确保数据一致性。可能的方案:
方案 1:过滤边(推荐)
在收集节点和边之后,过滤掉引用结果集外节点的边:
# 伪代码
node_ids = {node['id'] for node in nodes}
valid_edges = [
edge for edge in edges
if edge['source_id'] in node_ids and edge['target_id'] in node_ids
]方案 2:包含被引用的节点
当边引用初始结果集外的节点时,也包含该节点(可能超过 max_nodes):
# 伪代码
referenced_node_ids = set()
for edge in edges:
referenced_node_ids.add(edge['source_id'])
referenced_node_ids.add(edge['target_id'])
# 获取缺失的节点
missing_node_ids = referenced_node_ids - {node['id'] for node in nodes}
if missing_node_ids:
additional_nodes = fetch_nodes_by_ids(missing_node_ids)
nodes.extend(additional_nodes)方案 3:两阶段查询
- 首先,获取初始节点集(受 max_nodes 限制)
- 然后,只查询源节点和目标节点都在节点集中的边
相关文件
- 后端:
server/routers/graph_router.py- 子图查询端点 - 后端:
src/knowledge/graphbase.py- 图查询逻辑(LightRAG) - 前端:
web/src/components/GraphCanvas.vue- 图谱渲染组件 - 前端:
web/src/apis/graph_api.js- API 客户端
影响评估
- 严重程度: 高 - 导致图谱可视化无法工作
- 受影响用户: 所有查询 LightRAG 知识图谱的用户
- 临时方案: 前端过滤(已实现)
- 正确修复: 后端数据一致性(需要)
补充说明
该问题是在查询包含中文实体名称的 LightRAG 知识图谱时发现的。图谱包含汽车安全标准文档(GB 20071-2025)及相关技术术语和测量指标。
后端日志显示查询成功:
INFO: [kb_ab5c6bfdefb044c7ad08e8cc0f2da3a8] BFS subgraph query successful | Node count: 50 | Edge count: 139
然而,边的数量(139)远高于 50 个节点的完全连接图的预期值,这表明许多边引用了结果集外的节点。
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working