【问题标题】:Aggregation in arangodb using AQL使用 AQL 在 arangodb 中进行聚合
【发布时间】:2014-06-09 23:14:56
【问题描述】:

我正在 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”对象。从查询/结果中可以看出,每个对象都有一个称为“项目”的较小对象列表,每个项目都有数量和描述。

我想按成员对金额进行 SUM()。但是,像这样调整查询不起作用:

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 的字段。

查看结果我可以理解为什么:返回的结果使得 items 实际上是一个列表,具有数量/描述的对象列表。但我不明白如何正确引用或扩展未命名列表以返回 SUM() 函数的金额字段值。

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

如果您能提供帮助,请提前非常感谢! 马丁

PS 我已经完成了 arangodb 网站上的 AQL 教程并查看了手册,但真正帮助我的是加载更多示例查询以供查看。如果有人知道这样的资源或想分享他们自己的一些资源,'非常感谢。干杯!

【问题讨论】:

    标签: arangodb aql


    【解决方案1】:

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

    我通过创建一些这种格式的文档(有些只有一个项目)复制了您的数据:

    {
      "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()。 为了能够对项目进行 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] 使用未知函数 '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)) }
    • FLATTEN() 绝对是一个标准的数组函数。从 v2.7 开始,您还可以使用新的多星运算符进行扁平化:arangodb.com/2015/06/aql-improvements-for-2-7
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多