Luca Romagnoli
Luca Romagnoli

Reputation: 12455

Mongoose error on aggregate group

i have this model:

var Chat = new Schema({
    from: String,
    to: String,
    satopId: String,
    createdAt: Date
});
var Chat = mongoose.model('Chat', Chat);

I want do a query to do a query that returns the max created at grouping by to and from field. I tried with:

Chat.aggregate([
  {
    $group: {
      _id: '$to',
      from: '$from',
      createdAt: {
        $max: '$createdAt'
      }
    }
  },
  {
    $project: {
      _id: 1,
      createdAt: 1,
      from: 1,
      to: 1
    }
  }
], function(err, docs){

})

But this generates this error:

the group aggregate field 'from' must be defined as an expression inside an object

I don't understand what does it mean. How can i solve it?

Thanks

Upvotes: 3

Views: 2117

Answers (1)

Neil Lunn
Neil Lunn

Reputation: 151072

Anything "outside" if the _id expression in a $group statement requires a "grouping operator" of some sort.

Assuming you are happy with the idea of the "sole" grouping key to be the "to" field in your documents then you probably want something like $first:

    Chat.aggregate([
        { "$group": { 
            "_id": "$to", 
            "from": { "$first": "$from" }, 
            "createdAt": { "$max": "$createdAt" } 
        }}, 
        function (err, docs) {
            // do something here
        }
    ])

Otherwise if you want "distinct" values on "both" fields then they both belong as a composite value of the grouping key:

    Chat.aggregate([
        { "$group": { 
            "_id": {
                "to": "$to", 
                "from": "$from"
            },
            "createdAt": { "$max": "$createdAt" } 
        }}, 
        function (err, docs) {
            // do something here
        }
    ])

That's basically how it works. Either it's part of the key or something that needs a grouping operator just like with SQL.

Also note that your $project assertion is not really required as $group already does what you are asking there.

Upvotes: 2

Related Questions