Bazinga777
Bazinga777

Reputation: 5291

Mongoose get document as an array of arrays based on a key

I don't really know how to frame the question but what I have is the following schema in 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'
});

and I want to be able to query all the documents in the collection but the data should be arranged inside the array in the following format

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

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

    gatewayId: 2,
    timestamp: time2
    ....

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

   },
   {

    gatewayId: 3,
    timestamp: time2
    ....

   }] 
];

Is there a way that I can do this in mongoose instead of retrieving the documents and processing them again ?

Upvotes: 1

Views: 1285

Answers (1)

chridam
chridam

Reputation: 103445

Yes, it's possible. Consider the following aggregation pipeline in mongo shell. This uses a single pipeline stream comprising of just the $group operator, grouping all the documents by gatewayId and creating another array field that holds all the grouped documents. This extra field uses the accumulator operator $push on the system variable $$ROOT which returns the root document, i.e. the top-level document, currently being processed in the aggregation pipeline stage.

With the cursor returned from the aggregate() method, you can then use its map() method to create the desired final array. The following mongo shell demonstration describes the above concept:

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

This will output to shell the desired result.

To implement this in Mongoose, use the following aggregation pipeline 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);
    });

Upvotes: 2

Related Questions