ArangoDB:获取与所选节点有任何关系的每个节点
ArangoDB: Get every node, which is in any way related to a selected node
我在 ArangoDB 中有一个简单的节点链接图。如何从 1 个预选节点遍历 return 所有与其相关的节点?[=10=]
例如:
A→B, B→C, C→D, C→E, F→B, F→E
选择其中任何一个都应该return相同的结果(所有)。
我是 ArangoDB 的新手。
你需要的是 AQL graph traversal,自 ArangoDB 2.8 起可用。老版本提供了一组图相关的函数,但原生AQL遍历更快、更灵活,从3.0开始不再提供图函数。
AQL 遍历让您跟随连接到起始顶点的边,直至可变深度。可以访问每个遇到的顶点,例如用于过滤或构造结果,以及引导您到达该顶点的边以及从开始到结束的完整路径,包括顶点和边。
在您的情况下,只需要 returned 访问过的顶点的名称。您可以 运行 以下 AQL 查询,假设有一个文档集合 node
和一个边集合 links
并且它们包含此图的数据:
// 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
这只会return[ "B" ]
,因为遍历深度隐式为1..1
(min=1,max=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" ]
我们看到重复的节点 returned。原因是例如从 A 到 C 有多个路径(通过 B 和 B-F-E),并且查询 return 是每条路径的最后一个节点作为变量 v
。 (它实际上并不处理 所有 最大深度 10 的可能路径,但您可以设置遍历选项 OPTIONS {uniqueEdges: "none"}
来这样做。)
它可以帮助 return 格式化遍历路径以更好地理解正在发生的事情(即如何到达节点):
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 的所有节点都是 returned,无论起始顶点如何,我们可以发出以下测试查询:
FOR doc IN node
RETURN (
FOR v IN 0..10 ANY doc links OPTIONS {uniqueVertices: "global"}
SORT v._key
RETURN v._key
)
所有子数组应该看起来一样。如果您希望按遍历顺序 returned 节点名称,请删除 SORT 操作。希望这有帮助 =)
我在 ArangoDB 中有一个简单的节点链接图。如何从 1 个预选节点遍历 return 所有与其相关的节点?[=10=]
例如: A→B, B→C, C→D, C→E, F→B, F→E
选择其中任何一个都应该return相同的结果(所有)。
我是 ArangoDB 的新手。
你需要的是 AQL graph traversal,自 ArangoDB 2.8 起可用。老版本提供了一组图相关的函数,但原生AQL遍历更快、更灵活,从3.0开始不再提供图函数。
AQL 遍历让您跟随连接到起始顶点的边,直至可变深度。可以访问每个遇到的顶点,例如用于过滤或构造结果,以及引导您到达该顶点的边以及从开始到结束的完整路径,包括顶点和边。
在您的情况下,只需要 returned 访问过的顶点的名称。您可以 运行 以下 AQL 查询,假设有一个文档集合 node
和一个边集合 links
并且它们包含此图的数据:
// 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
这只会return[ "B" ]
,因为遍历深度隐式为1..1
(min=1,max=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" ]
我们看到重复的节点 returned。原因是例如从 A 到 C 有多个路径(通过 B 和 B-F-E),并且查询 return 是每条路径的最后一个节点作为变量 v
。 (它实际上并不处理 所有 最大深度 10 的可能路径,但您可以设置遍历选项 OPTIONS {uniqueEdges: "none"}
来这样做。)
它可以帮助 return 格式化遍历路径以更好地理解正在发生的事情(即如何到达节点):
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 的所有节点都是 returned,无论起始顶点如何,我们可以发出以下测试查询:
FOR doc IN node
RETURN (
FOR v IN 0..10 ANY doc links OPTIONS {uniqueVertices: "global"}
SORT v._key
RETURN v._key
)
所有子数组应该看起来一样。如果您希望按遍历顺序 returned 节点名称,请删除 SORT 操作。希望这有帮助 =)