遍历由 MongoDB 聚合查询生成的数组

m00*_*aca 4 javascript mongodb node.js aggregation-framework

大家下午好

我在 MongoDB 3.4 中处理聚合查询非常困难。我有一个问题,要求我将聚合查询的结果推送到一个名为的空数组中categories,我可以使用以下代码成功执行该操作:

var categories = [];

    database.collection("item").aggregate([{
        $group : {
            _id : "$category",
             num : {$sum : 1}
         }},
        {$sort:{_id:1}}]).toArray(function(err, data){

            categories.push(...data);
            callback(categories);
            console.log(categories);
        })

    }
Run Code Online (Sandbox Code Playgroud)

categories 看起来像这样:

[ { _id: 'Apparel', num: 6 },
{ _id: 'Books', num: 3 },
{ _id: 'Electronics', num: 3 },
{ _id: 'Kitchen', num: 3 },
{ _id: 'Office', num: 2 },
{ _id: 'Stickers', num: 2 },
{ _id: 'Swag', num: 2 },
{ _id: 'Umbrellas', num: 2 } ]
Run Code Online (Sandbox Code Playgroud)

接下来我有以下任务:

     In addition to the categories created by your aggregation query,
     include a document for category "All" in the array of categories
     passed to the callback. The "All" category should contain the total
     number of items across all categories as its value for "num". The
     most efficient way to calculate this value is to iterate through
     the array of categories produced by your aggregation query, summing        
     counts of items in each category.
Run Code Online (Sandbox Code Playgroud)

问题是,在我的.toArray()方法中,data参数有时像一个数组,有时则不是。例如,如果我想像这样将num键的值添加到categories数组中:categories.push(...data["num"])我收到一个错误说明undefined is not iterable.

由于我无法遍历每个data.num键,因此无法提取它的值并将其添加到所有data.num值的运行总数中。

我不明白这里发生了什么?

Ber*_*tel 5

您不需要使用应用程序逻辑来对数据进行分组,mongoDB 聚合就是为此任务进行的。另一种添加$group到您的查询与新的领域All$sum你的$num领域,$push所有文件到一个新的领域被称为categories

db.item.aggregate([{
    $group: {
        _id: "$category",
        num: { $sum: 1 }
    }
}, { $sort: { _id: 1 } }, {
    $group: {
        _id: 1,
        All: { $sum: "$num" },
        categories: {
            $push: {
                _id: "$_id",
                num: "$num"
            }
        }
    }
}])
Run Code Online (Sandbox Code Playgroud)

它给 :

{
    "_id": 1,
    "All": 23,
    "categories": [{
        "_id": "Swag",
        "num": 2
    }, {
        "_id": "Office",
        "num": 2
    }, {
        "_id": "Stickers",
        "num": 2
    }, {
        "_id": "Apparel",
        "num": 6
    }, {
        "_id": "Umbrellas",
        "num": 2
    }, {
        "_id": "Kitchen",
        "num": 3
    }, {
        "_id": "Books",
        "num": 3
    }, {
        "_id": "Electronics",
        "num": 3
    }]
}
Run Code Online (Sandbox Code Playgroud)

为了消耗输出,data是一个数组,访问第一个元素使用data[0]

var categories = [];

database.collection("item").aggregate([{
    $group: {
        _id: "$category",
        num: { $sum: 1 }
    }
}, { $sort: { _id: 1 } }, {
    $group: {
        _id: 1,
        All: { $sum: "$num" },
        categories: {
            $push: {
                _id: "$_id",
                num: "$num"
            }
        }
    }
}]).toArray(function(err, data) {

    var totalCount = data[0]["All"];
    console.log("total count is " + totalCount);

    categories = data[0]["categories"];

    for (var i = 0; i < categories.length; i++) {
        console.log("category : " + categories[i]._id + " | count : " + categories[i].num);
    }
})
Run Code Online (Sandbox Code Playgroud)