高效的 ArangoDB AQL 查询,可以找到集合中去往和来自相同文档的所有边
Efficient ArangoDB AQL query that can find all Edges in Collection that go To and From the same Documents
我有一个包含两个集合的 ArangoDB,一个用于文档,一个用于边缘,我想要一个高效的查询,它能够只返回共享相同 _to
和 _from
的边缘值。
例如,假设我的文档集合包含 A、B、C 和 D。
我们还假设我的边集合包含 X、Y 和 Z。
边 X 是 _from
A 和 _to
B。
边 Y 是 _from
A 和 _to
B。
Z 边是 _from
C 和 _to
D。
但是,我不知道X和Y基本上是同一条边,也不知道共享相似边的Documents是A&B。我的查询是找出这些重复的边。
目前为止我得到的是这样的:
FOR ec1 IN edge_collection
FOR ec2 IN edge_collection
FILTER ec1._key != ec2._key AND ec1._to == ec2._to AND ec1._from == ec2._from
RETURN ec1
这似乎行得通,但感觉效率极低。是否有更好的方法来执行此操作,或者这是 AQL 的最佳解决方案?
经过更多挖掘,我发现使用 COLLECT 语句的方法明显更快。
此外,完全披露,这是我在的基础上构建的。
LET duplicates = (
FOR ec IN edge_collection
COLLECT from = ec._from, to = ec._to WITH COUNT INTO count
FILTER count > 1
RETURN {
from: from,
to: to,
count: count
}
)
FOR d IN duplicates
FOR ec IN edge_collection
FILTER d.from == ec._from AND d.to == ec._to
RETURN ec
编辑:
基于@CodeManX 的回答,我的最终目标是能够删除或者 REMOVE 这些重复值。如果有人出于类似的目标偶然发现了这一点,这可能会有所帮助:
LET duplicates = (
FOR ec IN edge_collection
COLLECT from = ec._from, to = ec._to AGGREGATE count = LENGTH(1) INTO edges = ec._key
FILTER count > 1
RETURN { from, to, count, edges }
)
FOR d IN duplicates
LET key_to_delete = FIRST(d.edges)
REMOVE { _key: key_to_delete } IN edge_collection
您可以按 _from
和 _to
分组,计算每组有多少条边,并过滤出唯一组合:
FOR ec IN edge_collection
COLLECT from = ec._from, to = ec._to WITH COUNT INTO count
FILTER count > 1
RETURN { from, to, count }
或者,如果您还想 return 边缘键:
FOR ec IN edge_collection
COLLECT from = ec._from, to = ec._to INTO edges = ec._key
LET count = LENGTH(edges)
FILTER count > 1
RETURN { from, to, count, edges }
或者使用聚合而不是 post-计算:
FOR ec IN edge_collection
COLLECT from = ec._from, to = ec._to AGGREGATE count = LENGTH(1) INTO edges = ec._key
FILTER count > 1
RETURN { from, to, count, edges }
到 return 完整的边缘使用 INTO edges = ec
代替。您也可以只使用 INTO edges
,但每条边都将嵌套在对象 {"ec": … }
.
中
我有一个包含两个集合的 ArangoDB,一个用于文档,一个用于边缘,我想要一个高效的查询,它能够只返回共享相同 _to
和 _from
的边缘值。
例如,假设我的文档集合包含 A、B、C 和 D。 我们还假设我的边集合包含 X、Y 和 Z。
边 X 是 _from
A 和 _to
B。
边 Y 是 _from
A 和 _to
B。
Z 边是 _from
C 和 _to
D。
但是,我不知道X和Y基本上是同一条边,也不知道共享相似边的Documents是A&B。我的查询是找出这些重复的边。
目前为止我得到的是这样的:
FOR ec1 IN edge_collection
FOR ec2 IN edge_collection
FILTER ec1._key != ec2._key AND ec1._to == ec2._to AND ec1._from == ec2._from
RETURN ec1
这似乎行得通,但感觉效率极低。是否有更好的方法来执行此操作,或者这是 AQL 的最佳解决方案?
经过更多挖掘,我发现使用 COLLECT 语句的方法明显更快。
此外,完全披露,这是我在
LET duplicates = (
FOR ec IN edge_collection
COLLECT from = ec._from, to = ec._to WITH COUNT INTO count
FILTER count > 1
RETURN {
from: from,
to: to,
count: count
}
)
FOR d IN duplicates
FOR ec IN edge_collection
FILTER d.from == ec._from AND d.to == ec._to
RETURN ec
编辑:
基于@CodeManX 的回答,我的最终目标是能够删除或者 REMOVE 这些重复值。如果有人出于类似的目标偶然发现了这一点,这可能会有所帮助:
LET duplicates = (
FOR ec IN edge_collection
COLLECT from = ec._from, to = ec._to AGGREGATE count = LENGTH(1) INTO edges = ec._key
FILTER count > 1
RETURN { from, to, count, edges }
)
FOR d IN duplicates
LET key_to_delete = FIRST(d.edges)
REMOVE { _key: key_to_delete } IN edge_collection
您可以按 _from
和 _to
分组,计算每组有多少条边,并过滤出唯一组合:
FOR ec IN edge_collection
COLLECT from = ec._from, to = ec._to WITH COUNT INTO count
FILTER count > 1
RETURN { from, to, count }
或者,如果您还想 return 边缘键:
FOR ec IN edge_collection
COLLECT from = ec._from, to = ec._to INTO edges = ec._key
LET count = LENGTH(edges)
FILTER count > 1
RETURN { from, to, count, edges }
或者使用聚合而不是 post-计算:
FOR ec IN edge_collection
COLLECT from = ec._from, to = ec._to AGGREGATE count = LENGTH(1) INTO edges = ec._key
FILTER count > 1
RETURN { from, to, count, edges }
到 return 完整的边缘使用 INTO edges = ec
代替。您也可以只使用 INTO edges
,但每条边都将嵌套在对象 {"ec": … }
.