在Arangodb中使用AQL进行聚合

6
我将尝试一个相当基本的任务在arangodb中,使用SUM()聚合函数。
以下是一个有效的查询,它返回正确的数据(虽然还没有聚合):
FOR m IN pkg_spp_RegMem
FILTER m.memberId == "40289"
COLLECT member = m.memberId INTO g
RETURN { "memberId" : member, "amount" : g[*].m[*].items }

这将返回以下结果:
[
  {
    "memberId": "40289",
    "amount": [
      [
        {
          "amount": 50,
          "description": "some description"
        }
      ],
      [
        {
          "amount": 50,
          "description": "some description"
        },
        {
          "amount": 500,
          "description": "some description"
        },
        {
          "amount": 0,
          "description": "some description"
        }
      ],
      [
        {
          "amount": 0,
          "description": "some description"
        },
      ]
    ]
  }
]

我使用Collect来对结果进行分组,因为一个给定的memberId可能有多个'RegMem'对象。如您从查询/结果中看到的那样,每个对象都有一个称为“items”的较小对象列表,每个item都有一个金额和描述。

我想通过会员对金额进行求和。然而,像这样调整查询是不起作用的:

FOR m IN pkg_spp_RegMem
FILTER m.memberId == "40289"
COLLECT member = m.memberId INTO g
RETURN { "memberId" : member, "amount" : SUM(g[*].m[*].items[*].amount) }

它返回0,因为显然在展开的项目列表中找不到一个名为“amount”的字段。

从结果来看,我有点明白原因:结果被返回为一个列表,其中包含有关具有金额/描述的对象的列表的列表。但是我不知道如何正确引用或展开未命名的列表以返回SUM()函数的金额字段值。

理想情况下,查询应该按每个成员一行返回memberId和总金额,这样我就可以取消过滤并为所有成员执行。

非常感谢您的帮助! 马丁

附言:我已经完成了arangodb网站上的AQL教程并查阅了手册,但真正帮助我的是更多的示例查询供参考。如果有人知道这样的资源或想要分享自己的资源,"将不胜感激。谢谢!

1个回答

4

编辑:第一次误读了问题。第一个可以在编辑历史中看到,因为它还包含一些提示:

我通过创建一些格式相同的文档(以及一些只有一个项目的文档)来复制您的数据:

{
  "memberId": "40289",
  "items": [
    {
      "amount": 50,
      "description": "some description"
    },
    {
      "amount": 500,
      "description": "some description"
    }
  ]
}

根据这些类型的文档,您的非摘要查询确实应该如下所示:

FOR m IN pkg_spp_RegMem
FILTER m.memberId == "40289"
COLLECT member = m.memberId INTO g

RETURN { "memberId" : member, "amount" :  g[*].m[*].items }

返回的数据:
[
  {
    "memberId": "40289",
    "amount": [
      [
        {
          "amount": 50,
          "description": "some description"
        },
        {
          "amount": 0,
          "description": "some description"
        }
      ],
      [
        {
          "amount": 50,
          "description": "some description"
        },
        {
          "amount": 0,
          "description": "some description"
        }
      ],
      [
        {
          "amount": 50,
          "description": "some description"
        }
      ],
      [
        {
          "amount": 50,
          "description": "some description"
        },
        {
          "amount": 500,
          "description": "some description"
        }
      ],
      [
        {
          "amount": 0,
          "description": "some description"
        }
      ],
      [
        {
          "amount": 50,
          "description": "some description"
        },
        {
          "amount": 500,
          "description": "some description"
        }
      ]
    ]
  }
]

基于未汇总的版本,您需要循环遍历collect函数生成的组的项目,并在那里执行SUM()。为了能够对这些项目进行求和,您必须将它们FLATTEN()成单个列表,然后再进行汇总。
FOR m IN pkg_spp_RegMem
FILTER m.memberId == "40289"
COLLECT member = m.memberId INTO g

RETURN { "memberId" : member, "amount" :  SUM(
                                              FLATTEN(
                                                       (
                                                         FOR r in g[*].m[*].items
                                                         RETURN r[*].amount
                                                       )
                                                     )
                                             )
       }

这会导致:
[
  {
    "memberId": "40289",
    "amount": 1250
  }
]

非常感谢您的帮助!我之前不知道有 "flatten" 函数,但在调用它时出现了错误:“[1540] usage of unknown function 'FLATTEN()'”。请问这是用户自定义函数吗?无论如何,我非常感激您提供的答案,因为我使用了您提供的查询方式并进行了修改,得到了期望的结果:FOR m IN pkg_spp_RegMem FILTER m.memberId == "40289" COLLECT member = m.memberId INTO g RETURN { "memberId" : member, "amount" : SUM((FOR r IN g[].m[].items FOR i IN r RETURN i.amount)) } - Martin
1
FLATTEN() 绝对是一个标准的数组函数。从v2.7开始,您还可以使用新的多星运算符进行展平:https://www.arangodb.com/2015/06/aql-improvements-for-2-7/ - CodeManX

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接