Bazinga777
Bazinga777

Reputation: 5291

Mongodb $group returns only grouped item

I have the about 20,000 documents in the following format where the value.day gives me the date

    { 
    "_id" : ISODate("2016-01-04T23:00:11.000+0000"), 
    "value" : {
        "hour" : ISODate("2016-01-04T23:00:00.000+0000"), 
        "day" : ISODate("2016-01-04T00:00:00.000+0000"), 
        "time" : ISODate("2016-01-04T23:00:11.000+0000"), 
        "day_chan1" : 90.162, 
        "day_chan2" : 77.547, 
        "day_chan3" : 79.32, 
        "total_day_chan" : 247.029
    }
}
{ 
    "_id" : ISODate("2016-01-04T23:00:23.000+0000"), 
    "value" : {
        "hour" : ISODate("2016-01-04T23:00:00.000+0000"), 
        "day" : ISODate("2016-01-04T00:00:00.000+0000"), 
        "time" : ISODate("2016-01-04T23:00:23.000+0000"), 
        "day_chan1" : 90.167, 
        "day_chan2" : 77.549, 
        "day_chan3" : 79.322, 
        "total_day_chan" : 247.038
    }
}
{ 
    "_id" : ISODate("2016-01-04T23:00:35.000+0000"), 
    "value" : {
        "hour" : ISODate("2016-01-04T23:00:00.000+0000"), 
        "day" : ISODate("2016-01-04T00:00:00.000+0000"), 
        "time" : ISODate("2016-01-04T23:00:35.000+0000"), 
        "day_chan1" : 90.172, 
        "day_chan2" : 77.551, 
        "day_chan3" : 79.324, 
        "total_day_chan" : 247.047
    }
}

I want to perform an aggregation which would give me data from each day inside an array. Running the following command gives me two days but no data in them.

    db.temp4437190046D9electricity.aggregate([
      {
           $group: {
                '_id': '$value.day'
           }
      }
]);




  { "_id" : ISODate("2016-01-05T00:00:00Z") }
{ "_id" : ISODate("2016-01-04T00:00:00Z") }

How can I get the corresponding data for these two ids into these objects?

The expected output would look like

       { "_id" : ISODate("2016-01-04T00:00:00Z"),
             data: [{ 
    "hour" : ISODate("2016-01-04T23:00:00.000+0000"), 
    "day" : ISODate("2016-01-04T00:00:00.000+0000"), 
    "time" : ISODate("2016-01-04T23:00:11.000+0000"), 
    "day_chan1" : 90.162, 
    "day_chan2" : 77.547, 
    "day_chan3" : 79.32, 
    "total_day_chan" : 247.029
    }
    {
    "hour" : ISODate("2016-01-04T23:00:00.000+0000"), 
    "day" : ISODate("2016-01-04T00:00:00.000+0000"), 
    "time" : ISODate("2016-01-04T23:00:23.000+0000"), 
    "day_chan1" : 90.167, 
    "day_chan2" : 77.549, 
    "day_chan3" : 79.322, 
    "total_day_chan" : 247.038
    }
    { 
    "_id" : ISODate("2016-01-04T23:00:35.000+0000"), 
    "value" : {
    "hour" : ISODate("2016-01-04T23:00:00.000+0000"), 
    "day" : ISODate("2016-01-04T00:00:00.000+0000"), 
    "time" : ISODate("2016-01-04T23:00:35.000+0000"), 
    "day_chan1" : 90.172, 
    "day_chan2" : 77.551, 
    "day_chan3" : 79.324, 
    "total_day_chan" : 247.047
    }
    ]
     },
    { "_id" : ISODate("2016-01-04T00:00:00Z"),
      "data":[
    { 
        "hour" : ISODate("2016-01-05T14:00:00.000+0000"), 
        "day" : ISODate("2016-01-05T00:00:00.000+0000"), 
        "time" : ISODate("2016-01-05T14:16:44.000+0000"), 
        "day_chan1" : 63.611, 
        "day_chan2" : 56.801, 
        "day_chan3" : 58.129, 
        "total_day_chan" : 178.541
    }
    { 
        "hour" : ISODate("2016-01-05T14:00:00.000+0000"), 
        "day" : ISODate("2016-01-05T00:00:00.000+0000"), 
        "time" : ISODate("2016-01-05T14:16:56.000+0000"), 
        "day_chan1" : 63.644, 
        "day_chan2" : 56.833, 
        "day_chan3" : 58.161, 
        "total_day_chan" : 178.638
    }
]

}

Upvotes: 0

Views: 62

Answers (2)

Sede
Sede

Reputation: 61293

You need to use the $push accumulator operator in the $group stage to return an array of value for each document in a group of documents that share the same group by key; here value.day. Also you shouldn't use the $$ROOT variable because for large collection the resulting documents may exceed the BSON Document Size limit.

db.temp4437190046D9electricity.aggregate([
    { "$group": { 
        "_id": "$value.day",
        "data": { "$push": 
            { 
                "hour" : "$value.hour", 
                "day" : "$value.day", 
                "time" : "$value.time", 
                "day_chan1" : "$value.day_chan1", 
                "day_chan2" : "$value.day_chan2",  
                "day_chan3" : "$value.day_chan3", 
                "total_day_chan" : "$value.total_day_chan"
            }
        }
    }}
])

Using the sample data you provided yields:

{
    "_id" : ISODate("2016-01-04T00:00:00Z"),
    "data" : [
            {
                    "hour" : ISODate("2016-01-04T23:00:00Z"),
                    "day" : ISODate("2016-01-04T00:00:00Z"),
                    "time" : ISODate("2016-01-04T23:00:11Z"),
                    "day_chan1" : 90.162,
                    "day_chan2" : 77.547,
                    "day_chan3" : 79.32,
                    "total_day_chan" : 247.029
            },
            {
                    "hour" : ISODate("2016-01-04T23:00:00Z"),
                    "day" : ISODate("2016-01-04T00:00:00Z"),
                    "time" : ISODate("2016-01-04T23:00:23Z"),
                    "day_chan1" : 90.167,
                    "day_chan2" : 77.549,
                    "day_chan3" : 79.322,
                    "total_day_chan" : 247.038
            },
            {
                    "hour" : ISODate("2016-01-04T23:00:00Z"),
                    "day" : ISODate("2016-01-04T00:00:00Z"),
                    "time" : ISODate("2016-01-04T23:00:35Z"),
                    "day_chan1" : 90.172,
                    "day_chan2" : 77.551,
                    "day_chan3" : 79.324,
                    "total_day_chan" : 247.047
            }
    ]
}

Upvotes: 0

dikesh
dikesh

Reputation: 3125

This command will you the expected output. $push operator is missing from your aggregation command.

db.test.aggregate([
    {
         '$group' : {
             '_id': '$value.day',
             'data': {                                    
                 '$push' : '$value'
             }
         }

    }
]).pretty()

Upvotes: 1

Related Questions