繁体   English   中英

遍历MongoDB聚集查询产生的数组

[英]Iterating through array produced by MongoDB aggregation query

大家下午好

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

    }

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 } ]

接下来,我有以下任务:

  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. 

问题在于,似乎在我的.toArray()方法内部, data参数有时像数组,有时却像数组。 例如,如果我想将num键的值仅添加到categories数组中,例如: categories.push(...data["num"])我收到一条错误消息,指出undefined is not iterable

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

我对这里发生的事情不了解什么?

您无需使用应用程序逻辑来对数据进行分组,此任务进行了mongoDB聚合。 使用新字段将另一个$group添加到您的查询中, All $sum将您的$num字段和$push所有文档$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"
            }
        }
    }
}])

它给 :

{
    "_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
    }]
}

为了使用输出, 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);
    }
})

我想要实现的是推动或保持不变,我们稍后将看到一个类似以下内容的对象进入我的categories数组:

var allCategory = {
      _id: "All",
      num: [sum of all data.num values]
}

我最终.reduce()方法弄乱了,并在categories数组上使用了它。 我很幸运通过一些console.log -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);
        })

首先,我使用散布运算符将data所有对象推入categories 然后声明对categories运行.reduce() sum ,返回真正是data.numval["num"] data.num (控制台日志就是生命)。 我创建了allCategory文档/对象,然后使用.unshift将其放在我的categories数组的开头(此位置是.unshift ),然后使用回调。

我认为这是实现目标的一种简单方法,我必须对.toArray()中方法和变量的正确顺序进行一些试验和错误。 然而它奏效了,我学到了一些东西。 感谢@Bertrand Martel的帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM