Mongoose基于密钥将文档作为数组数组

时间:2015-11-10 18:06:22

标签: node.js mongodb mongoose

我真的不知道如何构建问题,但我拥有的是mongoose中的以下架构

new Schema({

                        gatewayId: { type: String, index: true },
                        timestamp: { type: Date, index: true },
                        curr_property:Number,
                        curr_property_cost:Number,
                        day_property:Number,
                        day_property_cost: Number,
                        curr_solar_generating: Number,
                        curr_solar_export:Number,
                        day_solar_generated:Number,
                        day_solar_export:Number,
                        curr_chan1:Number,
                        curr_chan2:Number,
                        curr_chan3:Number,
                        day_chan1:Number,
                        day_chan2:Number,
                        day_chan3:Number
},{
    collection: 'owlelecmonitor'
});

我希望能够查询集合中的所有文档,但数据应按以下格式排列在数组中

[ [{
    gatewayId: 1,
    timestamp: time
    ....
   },
   {

    gatewayId: 1,
    timestamp: time2
    ....
   }],
  [{
    gatewayId: 2,
    timestamp: time
    ....
   },
   {

    gatewayId: 2,
    timestamp: time2
    ....

   }],
  [{
    gatewayId: 3,
    timestamp: time
    ....

   },
   {

    gatewayId: 3,
    timestamp: time2
    ....

   }] 
];

有没有办法可以在mongoose中执行此操作,而不是检索文档并再次处理它们?

1 个答案:

答案 0 :(得分:1)

是的,这是可能的。考虑mongo shell中的以下聚合管道。这使用仅包含 $group 运算符的单个管道流,通过gatewayId对所有文档进行分组,并创建另一个包含所有分组文档的数组字段。此额外字段在系统变量 $push 上使用累加器运算符 $$ROOT ,该变量返回根文档,即顶级文档,当前正在在聚合管道阶段处理。

cursor 方法返回 aggregate() 后,您可以使用 map() 创建所需最终数组的方法。以下mongo shell演示描述了上述概念:

var result = db.owlelecmonitor.aggregate([
    {
        "$group": {
            "_id": "$gatewayId",
            "doc": {
                "$push": "$$ROOT"
            }
        }
    }
]).map(function (res){ return res.doc; });
printjson(result);

这将输出到shell所需的结果。

要在Mongoose中实现此功能,请使用以下聚合管道 builder

OwlelecMonitorModel
    .aggregate()
    .group({
        "_id": "$gatewayId",
        "doc": {
            "$push": "$$ROOT"
        }        
    })
    .exec(function (err, result) {
        var res = result.map(function (r){return r.doc;});
        console.log(res);
    });