findPaths
查找图结构中两个节点之间的所有路径。
基本用法
import { UserNode } from './entities/UserNode';
// 查找 Alice 到 Bob 的所有路径
const paths = await UserNode.findPaths({
fromId: 'alice-id',
toId: 'bob-id',
maxDepth: 5
});
返回结果
返回 GraphPath[] 数组,按路径长度和权重排序:
interface GraphPath<T> {
nodes: T[]; // 路径上的节点数组(按顺序,包括源和目标)
edges: EdgeInfo[]; // 路径上的边数组
length: number; // 路径长度(跳数)
totalWeight?: number; // 总权重(如果启用了边权重)
}
interface EdgeInfo {
sourceId: string;
targetId: string;
weight?: number;
properties?: Record<string, any>;
}
查询选项
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
fromId | string | 必填 | 源节点 ID |
toId | string | 必填 | 目标节点 ID |
maxDepth | number | 10 | 最大搜索深度(1-100) |
direction | 'in' | 'out' | 'both' | 'both' | 查询方向 |
where | RuleGroup | - | 路径节点过滤条件 |
edgeWhere | EdgeFilterOptions | - | 边过滤条件 |
查询方向
// 只沿出边方向搜索
const outPaths = await UserNode.findPaths({
fromId: 'alice-id',
toId: 'bob-id',
direction: 'out'
});
// 只沿入边方向搜索
const inPaths = await UserNode.findPaths({
fromId: 'alice-id',
toId: 'bob-id',
direction: 'in'
});
// 双向搜索(默认)
const allPaths = await UserNode.findPaths({
fromId: 'alice-id',
toId: 'bob-id',
direction: 'both'
});
节点约束
// 只经过特定类型的节点
const businessPaths = await UserNode.findPaths({
fromId: 'alice-id',
toId: 'bob-id',
maxDepth: 5,
where: {
combinator: 'and',
rules: [{ field: 'type', operator: '=', value: 'business' }]
}
});
边约束
// 只走高权重的边
const highValuePaths = await UserNode.findPaths({
fromId: 'alice-id',
toId: 'bob-id',
maxDepth: 5,
edgeWhere: {
weight: { min: 5 }
}
});
// 只走特定类型的边
const partnerPaths = await UserNode.findPaths({
fromId: 'alice-id',
toId: 'bob-id',
maxDepth: 5,
edgeWhere: {
properties: { category: 'partner' }
}
});
排序规则
返回的路径按以下规则排序:
- 路径长度升序 - 短路径优先
- 总权重升序(长度相同时)- 权重小的优先
const paths = await UserNode.findPaths({
fromId: 'alice-id',
toId: 'bob-id',
maxDepth: 5
});
// paths[0] 是最短路径(长度相同时权重最小)
console.log('最短路径:', paths[0].length);
console.log('最短路径总权重:', paths[0].totalWeight);
性能注意事项
- 路径搜索的复杂度随深度指数增长
- 建议根据图的密度合理设置
maxDepth - 对于密集图,推荐
maxDepth不超过 5 - 返回所有非循环路径(节点不重复)
实际应用场景
社交网络:六度分隔
// 查找两个用户之间的社交距离
const paths = await UserNode.findPaths({
fromId: 'user1',
toId: 'user2',
maxDepth: 6
});
if (paths.length > 0) {
console.log(`最短社交距离: ${paths[0].length}`);
console.log('连接路径:', paths[0].nodes.map(n => n.name).join(' → '));
}
知识图谱:概念关联
// 查找两个概念之间的关联路径
const paths = await Concept.findPaths({
fromId: 'concept-a',
toId: 'concept-b',
maxDepth: 4
});
路由规划:最短路径
// 查找城市间的所有路线
const routes = await City.findPaths({
fromId: 'beijing',
toId: 'shanghai',
maxDepth: 5,
edgeWhere: {
properties: { roadType: 'highway' }
}
});
// 第一条是最短路线(权重最小)
const shortestRoute = routes[0];
console.log(`最短距离: ${shortestRoute.totalWeight} km`);
框架集成
各框架提供响应式 Hooks:
- Angular
- React
- Vue
import { useGraphPaths } from '@aiao/rxdb-angular';
const paths = useGraphPaths(UserNode, () => ({
fromId: fromId(),
toId: toId(),
maxDepth: 5
}));
import { useGraphPaths } from '@aiao/rxdb-react';
const {
value: paths,
isLoading,
isEmpty
} = useGraphPaths(UserNode, {
fromId,
toId,
maxDepth: 5
});
<script setup lang="ts">
import { useGraphPaths } from '@aiao/rxdb-vue';
const {
value: paths,
isLoading,
isEmpty
} = toRefs(
useGraphPaths(UserNode, () => ({
fromId: fromId.value,
toId: toId.value,
maxDepth: 5
}))
);
</script>
参考
- 图结构定义
- findNeighbors - 查找邻居节点
- countNeighbors - 统计邻居数量