Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mongoose lean query, virtuals not showing

Tags:

mongoose

I have the following schema set up on mongoose, Im using version 3.6.17:

var PostSchema = new Schema({
    _id: { type: String, required: true, index: { unique: true } },
    video: { type: String, default: ''},
    cover: { type: String, default: ''},
    createdAt: { type: Date, default: Date.now },
    lastUpdate: { type: Date, default: Date.now }
    }, { autoIndex: true, toObject: { virtuals: true }, toJSON: { virtuals: true } });

And the following virtuals:

PostSchema.virtual('replied').get(function () {
    return false;
});

PostSchema.virtual('cover_url').get(function () {
    return config.cover.server + this.cover;
});

PostSchema.virtual('video_url').get(function () {
    return config.video.server + this.video;
});

When I do an aggregate query:

Post.aggregate(  { $match:  { replyTo: { $ne: "" }, author: user._id,  draft: false } },
                    { $project: {
                            _id: 1,
                            video: 1,
                            video_url: 1,
                            cover: 1,
                            cover_url: 1,
                            createdAt: 1,
                            lastUpdate: 1,
                            Ireplied : { $not: "$replied"} }
                          }, function ( ) ....

At this point the virtuals return but they return with the attribute this.cover or this.video undefined.

And when I do a Post.findOne(..).lean().populate(...) etc, I dont get the virtuals at all, neither with a Post.find().lean().populate(...)

Am I missing something on the Post schema, to be able to return the virtuals, or am I doing something wrong? And why with the aggregate operation the virtuals return the value "this.cover" as undefined?

Thank you!

like image 275
maumercado Avatar asked Aug 21 '13 16:08

maumercado


Video Answer


2 Answers

lean queries return raw MongoDB driver response as a plain js object. So, there are no getters, setters, virtuals or other "Mongoose magic" in it. See Api docs for more info.

The point of lean queries is to return your objects as fast as possible. If you need virtuals - use ordinary Mongoose queries.

As for aggregation, it's 100% MongoDB feature and Mongoose can't control it. So, when you calling aggregate from Mongoose it works the same as aggregate in MongoDB console. aggregate can't operate with virtuals, because there are no such fields in your database. Mongoose can't even cast your aggregation query according to your schema (like it's doing with findOneAndUpdate arguments), because aggregation changes the shape of the document on each step. See Mongoose API Docs and MongoDB Docs for more info.

like image 128
Leonid Beschastny Avatar answered Oct 24 '22 23:10

Leonid Beschastny


i found a solution you can use mongoose-lean-virtuals plugin

https://www.npmjs.com/package/mongoose-lean-virtuals

like image 4
SyraKozZ Avatar answered Oct 24 '22 22:10

SyraKozZ