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

Javascript 遍历MongoDB聚合查询生成的数组,javascript,node.js,mongodb,aggregation-framework,Javascript,Node.js,Mongodb,Aggregation Framework,大家下午好 我在MongoDB 3.4中处理聚合查询时遇到了很大困难。我有一个问题,就是要求我将聚合查询的结果推送到一个名为categories的空数组中,我已经成功地使用了以下代码: var categories = []; database.collection("item").aggregate([{ $group : { _id : "$category", num : {$sum : 1} }

大家下午好

我在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);
        })

    }
类别
如下所示:

[ { _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 } ]
接下来,我有以下任务:

问题是,在我的
.toArray()
方法中,
data
参数有时像数组,有时则不像。例如,如果我想将
num
键的值添加到
categories
数组中,如下所示:
categories.push(…data[“num]”)
我会收到一个错误,指出
undefined不可修改

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


关于这里发生的事情,我有什么不明白的吗?

您不需要使用应用程序逻辑对数据进行分组,mongoDB聚合就是为了完成此任务。在查询中添加另一个新字段
All
,将
$num
字段和所有文档添加到名为
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"
            }
        }
    }
}])
它给出:

{
    "_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
    }]
}
对于使用输出,
数据
是一个函数,要访问第一个元素,请使用
数据[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);
    }
})
var类别=[];
数据库.集合(“项”).聚合([{
$group:{
_id:“$category”,
num:{$sum:1}
}
},{$sort:{{u id:1}}{
$group:{
_id:1,
全部:{$sum:$num},
类别:{
$push:{
_id:“$\u id”,
num:“$num”
}
}
}
}]).toArray(函数(错误、数据){
var totalCount=数据[0][“全部”];
console.log(“总计数为”+totalCount);
类别=数据[0][“类别”];
对于(变量i=0;i
我想要实现的是推动或取消移动,我们马上就会看到一个类似这样的对象进入我的
类别
数组:

var allCategory = {
      _id: "All",
      num: [sum of all data.num values]
}
我最终弄乱了
.reduce()
方法,并在
类别
数组中使用了它。我通过一些
控制台获得了幸运。日志
-ing并最终制作了以下内容:

var categories = [];

    database.collection("item").aggregate([{
        $group : {
            _id : "$category",
             num : {$sum : 1}
         }},
        {$sort:{_id:1}}]).toArray(function(err, data){
            categories.push(...data);
            var sum = categories.reduce(function(acc, val){
                // console.log(acc, val["num"])
                return acc + val["num"]
            },0);

            var allCategory = {
                _id: "All",
                num: sum
            }
            categories.unshift(allCategory)
            callback(categories);
        })
首先,我使用扩展操作符将所有对象从
数据
推送到
类别
。然后在
categories
上声明
sum
运行
.reduce()
,返回
val[“num”]
的累积值,该值实际上是
数据.num
(控制台日志是life)。我创建
allCategory
文档/对象,然后使用
.unshift
将其放置在
categories
数组的开头(这是一个要求),然后使用回调


我认为这是实现我的目标的一种不切实际的方法,我不得不在我的
.toArray()
中对方法和变量的正确顺序进行一些尝试和错误。但它奏效了,我学到了一些东西。感谢@Bertrand Martel提供的帮助。

您的解决方案与我想要的非常接近,我感谢您的回复。总的来说,我认为在你的意见之后,我对我正在处理的事情有了更好的理解。我唯一不清楚的是是否需要将新的
{category:“All}
文档作为
数据数组的一部分。我将在您的下面发布我的答案,以便您可以看到我的意图。
var categories = [];

    database.collection("item").aggregate([{
        $group : {
            _id : "$category",
             num : {$sum : 1}
         }},
        {$sort:{_id:1}}]).toArray(function(err, data){
            categories.push(...data);
            var sum = categories.reduce(function(acc, val){
                // console.log(acc, val["num"])
                return acc + val["num"]
            },0);

            var allCategory = {
                _id: "All",
                num: sum
            }
            categories.unshift(allCategory)
            callback(categories);
        })