gpt4 book ai didi

ArangoDB:获取与所选节点有任何关系的每个节点

转载 作者:行者123 更新时间:2023-12-04 16:58:40 24 4
gpt4 key购买 nike

我在 ArangoDB 中有一个简单的节点链接图。如何从 1 个预选节点遍历并返回与其相关的所有节点?

例如:
A→B、B→C、C→D、C→E、F→B、F→E

选择它们中的任何一个都应该返回相同的结果(所有这些)。

我对 ArangoDB 很陌生。

最佳答案

您需要的是AQL graph traversal ,自 ArangoDB 2.8 起可用。旧版本提供了一组图相关的函数,但原生 AQL 遍历更快、更灵活,并且从 3.0 开始不再提供图函数。

AQL 遍历让您可以跟踪连接到起始顶点的边,直至可变深度。可以访问每个遇到的顶点,例如用于过滤或构建结果,以及引导您到达该顶点的边和从开始到结束的完整路径,包括顶点和边。

在您的情况下,只需要返回访问顶点的名称。您可以运行以下 AQL 查询,假设有一个文档集合 node和边缘集合 links它们包含此图的数据:

Example Graph

// follow edges ("links" collection) in outbound direction, starting at A
FOR v IN OUTBOUND "node/A" links
// return the key (node name) for every vertex we see
RETURN v._key

这只会返回 [ "B" ] ,因为遍历深度隐含 1..1 (最小值=1,最大值=1)。如果我们增加最大深度,那么我们也可以包括间接连接的节点:
FOR v IN 1..10 OUTBOUND "node/A" links
RETURN v._key

这会给我们 [ "B", "C", "D", "E"] .如果我们看一下图,这是正确的:我们只沿着从我们来自的顶点指向另一个顶点(箭头的方向)的边。反过来,我们可以使用 INBOUND ,但在你的情况下,我们想忽略边缘的方向,无论如何都要遵循:
FOR v IN 1..10 ANY "node/A" links
RETURN v._key

结果一开始可能有点出人意料: [ "B", "C", "D", "E", "F", "B", "F", "E", "C", "D", "B" ]
我们看到返回了重复的节点。原因是例如从 A 到 C 有多条路径(通过 B 和 B-F-E),并且查询返回每条路径的最后一个节点作为变量 v . (它实际上并不处理 所有 可能的路径,最大深度为 10,但您可以设置遍历选项 OPTIONS {uniqueEdges: "none"} 来执行此操作。)

它可以帮助返回格式化的遍历路径以更好地了解正在发生的事情(即如何到达节点):
FOR v, e, p IN 1..10 ANY "node/A" links OPTIONS {uniqueEdges: "path"}
RETURN CONCAT_SEPARATOR(" - ", p.vertices[*]._key)

结果:
[
"A - B",
"A - B - C",
"A - B - C - D",
"A - B - C - E",
"A - B - C - E - F",
"A - B - C - E - F - B",
"A - B - F",
"A - B - F - E",
"A - B - F - E - C",
"A - B - F - E - C - D",
"A - B - F - E - C - B"
]

图中有一个循环,但不能无限循环,因为10跳后超过了最大深度。但正如您在上面看到的,它甚至没有达到 10 的深度,而是停止,因为(默认)选项是不沿着每条路径两次边缘( uniqueEdges: "path" )。

无论如何,这不是想要的结果。一个便宜的技巧是使用 RETURN DISTINCT , COLLECT或类似的东西来删除重复项。但是我们最好调整遍历选项,以免不必要地跟随边缘。
uniqueEdges: "global"仍然会包含 B 节点两次,但 uniqueVertices: "global"给出了想要的结果。另外, bfs: true在这种情况下可以使用广度优先搜索。不同之处在于到 F 节点的路径更短(A-B-F 而不是 A-B-C-E-F)。通常,您应该使用的确切选项在很大程度上取决于数据集和您的问题。

还有一个问题需要解决:遍历不包括起始顶点(除了 p.vertices[0] 中的每条路径)。通过将最小深度设置为 0,可以使用 ArangoDB 3.0 或更高版本轻松解决此问题:
FOR v IN 0..10 ANY "node/A" links OPTIONS {uniqueVertices: "global"}
RETURN v._key
[ "A", "B", "C", "D", "E", "F" ]
为了验证从 A 到 F 的所有节点都被返回,无论起始顶点如何,我们可以发出以下测试查询:
FOR doc IN node
RETURN (
FOR v IN 0..10 ANY doc links OPTIONS {uniqueVertices: "global"}
SORT v._key
RETURN v._key
)

所有子数组应该看起来都一样。如果您希望以遍历顺序返回节点名称,请删除 SORT 操作。希望这会有所帮助 =)

关于ArangoDB:获取与所选节点有任何关系的每个节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38744127/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com