我有一个物料清单,在ArangoDB中表示为有向无环图。材料明细表中每个零件的数量在边上表示,而零件名称则由节点的键表示。我想编写一个查询,该查询从祖先节点向下遍历DAG,并通过零件名称将每个零件的数量相加。例如,考虑以下图形:
Qty: 2 Qty: 1
Widget +------> Gadget +------> Stuff
+ + Qty: 4
| Qty: 1 +---------> Thing
+----------------------------^
Widget
包含两个Gadgets
,每个包含一个Stuff
和四个Things
。 Widget
还包含一个Thing
。因此,我想编写一个AQL查询,该查询从小部件开始遍历图并返回:
{
"Gadget": 2,
"Stuff": 2,
"Thing": 9
}
我相信collect aggregate
可能是我在这里的朋友,但是我还没有找到合适的咒语。挑战的一部分是,一个部分的所有后代数量都需要乘以其父代数量。什么样的查询看起来像对10层深度的DAG有效地执行此求和?
答案 0 :(得分:2)
想到三个可能的选择:
1.-从路径返回值,然后汇总应用服务器中的数据:
FOR v,e,p IN 1..2 OUTBOUND 'test/4719491'
testRel
RETURN {v:v.name, p:p.edges[*].qty}
这将返回小配件2,东西[2,1],事物[2,4],事物[1]
2.-枚举路径上的边,以直接获得结果:
FOR v,e,p IN 1..2 OUTBOUND 'test/4719491'
testRel
let e0 = p.edges[0].qty
let e1 = NOT_NULL(p.edges[1].qty,1)
collect itemName = v.name aggregate items = sum(e0 * e1)
Return {itemName: itemName, items: items}
这会正确返回小配件2,东西2,东西9。
这显然需要您事先掌握级别。
3.-编写类似于现有“ SUM”函数的自定义函数“ multiply”,以便您可以将数组的值相乘。该查询将类似于以下内容:
let vals = (FOR v,e,p IN 1..2 OUTBOUND 'test/4719491'
testRel
RETURN {itemName:v.name, items:SUM(p.edges[*].qty)})
for val in vals
collect itemName = val.itemName Aggregate items = sum(val.items)
return {itemName: itemName, items: items}
因此,您的函数将替换内部子选择中的SUM。 Here是有关自定义函数的文档