Reputation: 16066
I want to calculate an average every time a new element is added to a collection. Basically, what I'm trying to calculate is inside a "pre save" hook, but I'm always getting undefined results.
This is the schema:
var CommentSchema = new Schema({
posted:{
type:Date,
default:Date.now
},
text:{
type: String
},
owner:{
_id:{
type: Schema.Types.ObjectId, ref: 'User'
},
displayName:{
type:String
}
},
reference: {
objectType:{
type: String,
enum: [ 'document','element','process', 'project', 'story']
},
_id:{
type: Schema.Types.ObjectId
}
},
sentiment:{
score:{
type:Number,
default:0.0
},
comparative:{
type:Number,
default:0.0
}
}
});
CommentSchema.pre('save', function(next){
var thiz = this;
// this code is inside another callback, that's the reason I'm using thiz
if(thiz.reference.objectType ==='element'){
mongoose.models['Comment'].aggregate([
{ $match:{'reference._id': mongoose.Types.ObjectId(thiz.reference._id)} },
{ $group:{'reference._id': mongoose.Types.ObjectId(thiz.reference._id), average:{$avg:'$sentiment.score'}}}
],
function(err, result){
console.log('------------------');
console.log('result',result);
console.log('------------------');
}
);
}
next();
});
I always get undefined results, however, if I query like the example below, I get the list of comments.
db.getCollection('comments').find({"reference._id":ObjectId("55a69276242aa1837a1ecb6c")})
Is there anything I am missing in the aggregate?
Upvotes: 1
Views: 255
Reputation: 386
{ $group: { _id: null, average: { $avg: '$sentiment.score' } } }
"The _id field is mandatory; however, you can specify an _id value of null to calculate accumulated values for all the input documents as a whole."
http://docs.mongodb.org/manual/reference/operator/aggregation/group/
$group: { _id: <expression>, <field1>: { <accumulator1> : <expression1> }, ... } }
Upvotes: 1