【问题标题】:How to $add together a subset of elements of an array in mongodb aggregation?如何在mongodb聚合中将数组元素的子集加在一起?
【发布时间】:2015-02-06 12:31:27
【问题描述】:

这是我要解决的问题:

  • 每个文档都包含一个由 30 个整数组成的数组
  • 文档在特定条件下分组(此处不相关)
  • 在对它们进行分组时,我想:
    • 将每个文档的数组的最后 29 个元素相加(跳过第一个元素)
    • 在同一组中将之前的结果相加,并返回

数据结构很难改变,我负担不起迁移 + 我仍然需要 30 个值用于其他目的。这是我尝试过的,但没有成功:

db.collection.aggregate([
    {$match: {... some matching query ...}},
    {$project: {total_29_last_values: {$add: ["$my_array.1", "$my_array.2", ..., "$my_array.29"]}}},
    {$group: {
        ... some grouping here ...
        my_result: {$sum: "$total_29_last_values"}
    }}
])

理论上(恕我直言)这应该可行,鉴于 $add 在 mongodb 文档中的定义,但由于某种原因它失败了:

exception: $add only supports numeric or date types, not Array

也许不支持将数组的元素相加,但这似乎很奇怪...

感谢您的帮助!

【问题讨论】:

  • 请发布您收藏的示例文档。

标签: mongodb aggregation-framework


【解决方案1】:

来自docs

$add 表达式的语法如下:

{ $add: [<expression1>, <expression2>, ... ] }

参数可以是任何有效的表达式,只要它们解析为 可以是所有数字,也可以是数字和日期。

它明确指出$add 运算符只接受数字或日期。

$my_array.1 解析为 empty 数组。例如,[]。 (您始终可以在特定索引中查找匹配项,例如 {$match:{"a.0":1}},但不能从数组的特定索引中获取值。为此,您需要使用 $$slice 运算符。这是目前一个未解决的问题:JIRA1, JIRA2)

$add 表达式变为$add:[[],[],[],..]

$add not 将数组作为输入,因此您会收到错误消息,指出它不支持数组作为输入。

你需要做的是:

  • Match 文件。
  • Unwind my_array 字段。
  • Group 一起根据每个文档的_id 得到总和 数组中跳过第一个元素的所有元素。
  • Project 每个分组文档的总和字段。
  • 再次group文档根据条件得到总和。

舞台操作员:

db.collection.aggregate([
{$match:{}}, // condition
{$unwind:"$my_array"},
{$group:{"_id":"$_id",
         "first_element":{$first:"$my_array"},
         "sum_of_all":{$sum:"$my_array"}}},
{$project:{"_id":"$_id",
           "sum_of_29":{$subtract:["$sum_of_all","$first_element"]}}},
{$group:{"_id":" ",  // whatever condition
         "my_result":{$sum:"$sum_of_29"}}}
])

【讨论】:

  • 谢谢,它工作得很好,我不得不稍微调整一下以适应我文档的实际结构。另外,我不知道$my_array.1 解析为一个包含一个元素的数组...
  • @getmax0 它实际上返回一个空数组,而不是元素。这是目前未解决的开放问题。在我的回答中更新了这一点。
猜你喜欢
  • 2019-10-27
  • 2020-10-19
  • 2017-03-12
  • 2017-02-12
  • 2018-04-30
  • 2021-02-14
  • 1970-01-01
  • 1970-01-01
  • 2017-05-27
相关资源
最近更新 更多