node.js - 一个请求中的多个聚合函数

标签 node.js mongodb mongoose mongodb-query aggregation-framework

我有一个数据集如下:

{
  item: '123',
    array: [{
      array2:[{
        array3: [{
          property1: 1234
        }]
      }],
      anotherArray: [{
        property2: 1234
      }]
    }]
}

我正在尝试在同一请求中聚合属性 2 和属性 1 的总和。 这是我当前的聚合函数:

Item.aggregate([
            {$match: {itemId: 1234}},
            {$unwind: "$array"},
            {$unwind: "$array.array2"},
            {$unwind: "$array.array2.array3"},
            {$unwind: "$array.anotherArray"},
            {$group: {
                _id: 0,
                property1: {$sum: '$array.array2.array3.property1'},
                property2: {$sum: '$array.anotherArray.property2'}

            }},
            {$project: {
                _id: 0,
                property1: "$property1",
                property2: "$property2",

            }},
        ], function (err, aggregate) {
            callback(null, aggregate);
        });

问题在于,属性一和属性二的合计结果始终是应有值的两倍。

我猜问题出在“anotherArray”的 $unwind 上,因为当我删除它时,我得到了正确的聚合值。

是否可以使用一个聚合函数对多个数组进行聚合?

目前,我只是使用异步并行方式向数据库发出 2 个不同的请求,但我想在将来进行更复杂的聚合,而无需进行额外的数据库调用。

最佳答案

如前所述,该结构不是一个好的结构,可能应该对其意图进行审查。确实不清楚为什么它是这样结构化的,或者在任何一种情况下数组中的其他内容是否会弄乱这里的结果。

但是,当文档中有多个数组时,有一种通用方法,基本上是单独处理每个数组,并首先获取每个文档的“总计”。然后将所有文档的总数相加:

Item.aggregate([
    // Unwind only 1 inner array first
    { "$unwind": "$array" },
    { "$unwind": "$array.array2" },
    { "$unwind": "$array.array2.array3" },

    // Group back the sum of the element and the first of the other array
    // and only per document
    { "$group": {
        "_id": "$_id",
        "property1": { "$sum": "$array.array2.array3.property1" },
        "anotherArray": { "$first": "$array.anotherArray" }
    }},

    // Unwind the other array
    { "$unwind": "$anotherArray" },

    // Group back the total and the first summed per document
    { "$group": {
        "_id": "$_id",
        "property1": { "$first": "$property1" },
        "property2": { "$sum": "$anotherArray.property2" }
    }},

    // Total all documents and output
    { "$group": {
        "_id": null,
        "property1": { "$sum": "$property1" },
        "property2": { "$sum": "$property2" },
    }},
    { "$project": {
        "_id": 0,
        "property1": 1,
        "property2": 1
    }}
],callback);

因此,通过一次仅包含一个数组并仅在原始文档中获取总计,您可以避免为另一个数组的每个展开项目创建多个副本的重复问题。通过离散文档总计,可以轻松地从所需选择中获取总体总计。

关于node.js - 一个请求中的多个聚合函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29124585/

相关文章:

javascript - 每 3 个月和 6 个月在 later.js 上重复一次,从特定日期开始说明

node.js - 使用 Typescript 在 Mongoose 中链接 ES6 Promise

javascript - 正确编写数据库填充逻辑的集成测试

javascript - 在响应之前向文档添加其他字段

node.js - 如何解决node.js中将数据保存到mongodb的问题?

node.js - MongoDB 按 ID 分组,然后按日期分组

javascript - 在 Node.js 项目中连接多个 Mongo DB

node.js - 文档中的空字段会占用 Mongoose 中的空间吗?

node.js - Mongoose:对 $skip 和 $limit 之后的所有字段数求和

node.js - 使用 JADE 的 https nodeJS 无法正确显示网站