Mongoose VMs in MongoDB aggregate
My Mongoose schema looks like this:
var DSchema = new mongoose.Schema({
original_y: {type: Number},,
new_y: {type: Number},,
date: {type: Date},
dummy: [dummyEmbeddedDocuments]
}, toObject: { virtuals: true }, toJSON: { virtuals: true}
});
DSchema.virtual('dateformatted').get(function () {
return moment(this.date).format('YYYY-MM-DD HH:mm:ss');
});
module.exports = mongoose.model('D', DSchema);
The document in my schema will look like this:
{
id:1,
original_y: 200,
new_y: 140,
date: 2015-05-03 00:00:00.000-18:30,
dummy: [
{id:1, storage:2, cost: 10},
{id:2, storage:0, cost: 20},
{id:3, storage:5, cost: 30},
]
}
My request:
Item.aggregate([
{
"$match": {
"dummy.storage": {"$gt": 0}
}
},
{
"$unwind": "$dummy"
},
{
"$project": {
"original_y": 1,
"new_y": 1,
"dateformatted": 1,
"dummy.id": "$dummy.id",
"dummy.storage": "$dummy.storage",
"dummy.cost": "$dummy.cost",
"dummy.tallyAmount": {
"$divide": [
{ "$add": ["$new_y","$original_y"] },
"$dummy.cost"
]
}
}
},
{
"$group": {
"_id": "_$id",
"original_y": { "$first": "$original_y" },
"dateformatted": { "$first": "$dateformatted" },
"new_y": { "$first": "$new_y" },
"dummy": {
"$addToSet": "$dummy"
}
}
}
]).exec(callback);
However, this query returns the VIRTUAL dateformatted attribute as NULL. Any thoughts on why this is happening?
source to share
Several notes in the docs deal with why this is the case:
- The arguments are not tied to the model schema because operators
$project
allow you to override the "shape" of documents at any stage in the pipeline, which might leave documents in an incompatible format.- The documents returned are plain javascript objects, not mongoose documents (since any form of document can be returned).
But that goes beyond that, because the operation aggregate
is done on the server side where no client side Mongoose concepts like virtual exist.
As a result, you will need to include the field date
in the steps $project
and $group
and add your own field dateformatted
to the results in the value-based code date
.
source to share