过滤掉 ArangoDB 遍历中的中间点
FIltering out intermediate points in ArangoDB traversal
通过 "contains" 给出的图表我有以下内容:
- D 包含 LibD
- C 包含 LibC 和 D
- B 包含 LibB 和 D
- A 包含 LibA、B 和 C
使用:
FOR v,e,p IN 1..50 INBOUND 'pmconfig/899018092734' pm_content RETURN p.vertices
我得到以下路径:
- A->B->LibB
- A->B->D->LibD
- A->B->D
- A->B
- A->LibA
- A->C->LibC
- A->C->D->LibD
- A->C->D
- A->C
我想过滤掉中间点,所以我得到:
- A->B->LibB
- A->B->D->LibD
- A->LibA
- A->C->LibC
- A->C->D->LibD
如果 LibX 元素是叶子,我可以添加一个过滤器,例如
FILTER LENGTH(EDGES(pm_content,v._id,'inbound'))==0
但假设我有一条路径:A->B->C->D->B
在这种情况下,我会过滤掉所有内容。我想要的是
A->B->C->D,因为当它识别出循环时步行应该停止。
如何构造一个过滤器来去除中间点?具体来说,只有那些以叶节点结尾或所有内容链接都指向已遍历的顶点。
要过滤 "unfinished paths",我们需要预测遍历器是否能够沿着图继续向下移动。
唯一的方法就是尝试 - 所以我们在子查询中添加了从当前顶点(v
)开始的第二次遍历,最多走一步。
子查询将return两种可能的结果:[1]
如果有更多的节点,[]
如果没有。我们可以使用 LENGTH()
函数对此进行测试。
然后我们将使用此信息从结果中过滤未完成的路径:
FOR v,e,p IN 1..50 INBOUND 'pmconfig/899018092734' pm_content
LET next = (FOR x IN 1 INBOUND v pm_content LIMIT 1 RETURN 1)
FILTER LENGTH(next) == 0
RETURN p.vertices
让我们尝试在 Traversal Graph 上进行测试;我们将方向更改为 OUTBOUND
,因为这样可以轻松获得更多结果。我们将输出限制为仅提供 _key
,因此我们可以毫无问题地重新验证结果。
var examples = require("org/arangodb/graph-examples/example-graph.js");
var graph = examples.loadGraph("traversalGraph");
db._query(`
FOR v,e,p IN 1..50 OUTBOUND 'circles/A' GRAPH 'traversalGraph'
LET next = (FOR x IN 1 OUTBOUND v GRAPH 'traversalGraph' LIMIT 1 RETURN 1)
FILTER LENGTH(next) == 0
RETURN p.vertices[*]._key
`).toArray()
[
[ "A", "B", "C", "D" ],
[ "A", "B", "E", "F" ],
[ "A", "G", "H", "I" ],
[ "A", "G", "J", "K" ]
]
如我们所见,我们只获得了到端点的路径 - 正如预期的那样。
通过 "contains" 给出的图表我有以下内容:
- D 包含 LibD
- C 包含 LibC 和 D
- B 包含 LibB 和 D
- A 包含 LibA、B 和 C
使用:
FOR v,e,p IN 1..50 INBOUND 'pmconfig/899018092734' pm_content RETURN p.vertices
我得到以下路径:
- A->B->LibB
- A->B->D->LibD
- A->B->D
- A->B
- A->LibA
- A->C->LibC
- A->C->D->LibD
- A->C->D
- A->C
我想过滤掉中间点,所以我得到:
- A->B->LibB
- A->B->D->LibD
- A->LibA
- A->C->LibC
- A->C->D->LibD
如果 LibX 元素是叶子,我可以添加一个过滤器,例如
FILTER LENGTH(EDGES(pm_content,v._id,'inbound'))==0
但假设我有一条路径:A->B->C->D->B
在这种情况下,我会过滤掉所有内容。我想要的是 A->B->C->D,因为当它识别出循环时步行应该停止。
如何构造一个过滤器来去除中间点?具体来说,只有那些以叶节点结尾或所有内容链接都指向已遍历的顶点。
要过滤 "unfinished paths",我们需要预测遍历器是否能够沿着图继续向下移动。
唯一的方法就是尝试 - 所以我们在子查询中添加了从当前顶点(v
)开始的第二次遍历,最多走一步。
子查询将return两种可能的结果:[1]
如果有更多的节点,[]
如果没有。我们可以使用 LENGTH()
函数对此进行测试。
然后我们将使用此信息从结果中过滤未完成的路径:
FOR v,e,p IN 1..50 INBOUND 'pmconfig/899018092734' pm_content
LET next = (FOR x IN 1 INBOUND v pm_content LIMIT 1 RETURN 1)
FILTER LENGTH(next) == 0
RETURN p.vertices
让我们尝试在 Traversal Graph 上进行测试;我们将方向更改为 OUTBOUND
,因为这样可以轻松获得更多结果。我们将输出限制为仅提供 _key
,因此我们可以毫无问题地重新验证结果。
var examples = require("org/arangodb/graph-examples/example-graph.js");
var graph = examples.loadGraph("traversalGraph");
db._query(`
FOR v,e,p IN 1..50 OUTBOUND 'circles/A' GRAPH 'traversalGraph'
LET next = (FOR x IN 1 OUTBOUND v GRAPH 'traversalGraph' LIMIT 1 RETURN 1)
FILTER LENGTH(next) == 0
RETURN p.vertices[*]._key
`).toArray()
[
[ "A", "B", "C", "D" ],
[ "A", "B", "E", "F" ],
[ "A", "G", "H", "I" ],
[ "A", "G", "J", "K" ]
]
如我们所见,我们只获得了到端点的路径 - 正如预期的那样。