ArangoDB-DAG中后代属性的总和

时间:2018-12-05 18:42:12

标签: arangodb directed-acyclic-graphs aql

我有一个物料清单,在ArangoDB中表示为有向无环图。材料明细表中每个零件的数量在边上表示,而零件名称则由节点的键表示。我想编写一个查询,该查询从祖先节点向下遍历DAG,并通过零件名称将每个零件的数量相加。例如,考虑以下图形:

       Qty: 2          Qty: 1         
Widget +------> Gadget +------> Stuff 
    +               +  Qty: 4         
    |  Qty: 1       +---------> Thing 
    +----------------------------^    

Widget包含两个Gadgets,每个包含一个Stuff和四个ThingsWidget还包含一个Thing。因此,我想编写一个AQL查询,该查询从小部件开始遍历图并返回:

{
  "Gadget": 2,
  "Stuff": 2,
  "Thing": 9
}

我相信collect aggregate可能是我在这里的朋友,但是我还没有找到合适的咒语。挑战的一部分是,一个部分的所有后代数量都需要乘以其父代数量。什么样的查询看起来像对10层深度的DAG有效地执行此求和?

1 个答案:

答案 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是有关自定义函数的文档