跳到主要内容

图结构 (Graph)

图用于表达点与边组成的关系网络,常见于社交关系、知识图谱、推荐系统等。

在 Aiao 中可采用两种方式建模:

  • 使用多对多关系(邻接集)——简单直接,适合轻量场景
  • 使用 @GraphEntity——自动生成边表,支持边权重与边属性

多对多方式(邻接集)

可用多对多关系实现用户之间的"好友"关系(无向图):

GraphEntity 方式(自动边表)

@GraphEntity 会将类标记为图实体,并在运行期根据配置生成一张"边表"(命名为 节点实体名_edges)。

import { GraphEntity, GraphEntityBase, PropertyType } from '@aiao/rxdb';

@GraphEntity({
name: 'UserNode',
properties: [
{ name: 'name', type: PropertyType.string },
{ name: 'type', type: PropertyType.string }
],
features: {
// graphType: 'undirected-graph' | 'directed-graph'(默认无向图)
graphWeight: true, // 边是否带权重(生成 weight 字段)
graphProperties: true // 是否启用边属性 JSON(生成 properties 字段)
}
})
export class UserNode extends GraphEntityBase {}

自动边表:

  • 表名:UserNode_edges(与节点实体同命名空间)
  • 字段:weight?: numberproperties?: json(由 features 决定)

GraphRepository 图查询能力

GraphRepository 继承自 Repository,提供图遍历和路径查询能力。

查询邻居节点

// 查询直接好友(1跳)
const friends = await UserNode.findNeighbors({
entityId: 'alice-id',
level: 1
});

// 查询好友的好友(2度人脉,1跳+2跳)
const extendedNetwork = await UserNode.findNeighbors({
entityId: 'alice-id',
level: 2
});

// 结果包含节点、边信息和跳数
// { node: 邻居节点, edge: { sourceId, targetId, direction, weight, properties }, level: 跳数 }

查询选项

选项类型默认值说明
entityIdstring必填起始节点 ID
levelnumber1最大跳数(1-10)
direction'in' | 'out' | 'both''both'查询方向
whereRuleGroup-节点过滤条件
edgeWhereEdgeFilterOptions-边过滤条件(权重、属性)

统计邻居数量

// 高性能统计,不返回完整节点数据
const friendCount = await UserNode.countNeighbors({
entityId: 'alice-id',
level: 1
});

查询路径

// 查找两个节点之间的所有路径
const paths = await UserNode.findPaths({
fromId: 'alice-id',
toId: 'bob-id',
maxDepth: 5
});

// 路径结果
// {
// nodes: [节点数组,按顺序],
// edges: [边数组,包含 sourceId、targetId、weight、properties],
// length: 跳数,
// totalWeight: 总权重
// }

路径查询选项

选项类型默认值说明
fromIdstring必填源节点 ID
toIdstring必填目标节点 ID
maxDepthnumber10最大搜索深度(1-100)
direction'in' | 'out' | 'both''both'查询方向
whereRuleGroup-路径节点过滤条件
edgeWhereEdgeFilterOptions-边过滤条件

边操作

// 添加边(可选权重和属性)
await UserNode.addEdge(userA, userB, 8, {
category: 'colleague',
since: '2024-01-01'
});

// 移除边
await UserNode.removeEdge(userA, userB);

边过滤条件

// 按权重过滤
const highValueFriends = await UserNode.findNeighbors({
entityId: 'alice-id',
level: 1,
edgeWhere: {
weight: { min: 5, max: 10 }
}
});

// 按边属性过滤
const businessPartners = await UserNode.findNeighbors({
entityId: 'alice-id',
level: 2,
edgeWhere: {
properties: { category: 'business' }
}
});

框架集成

各框架提供响应式 Hooks 来订阅图查询结果:

import { useGraphNeighbors, useCountNeighbors, useGraphPaths } from '@aiao/rxdb-angular';

// 响应式邻居查询
const neighbors = useGraphNeighbors(UserNode, {
entityId: signal('alice-id'),
level: signal(2)
});

// 响应式邻居数量
const count = useCountNeighbors(UserNode, {
entityId: signal('alice-id'),
level: signal(1)
});

// 响应式路径查询
const paths = useGraphPaths(UserNode, {
fromId: signal('alice-id'),
toId: signal('bob-id'),
maxDepth: signal(5)
});