10

我在猫鼬上设置了以下架构,我使用的是 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 } });

以及以下虚拟:

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;
});

当我进行聚合查询时:

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 ( ) ....

此时虚拟对象返回,但它们返回的属性 this.cover 或 this.video 未定义。

当我做 Post.findOne(..).lean().populate(...) 等时,我根本没有得到虚拟,也没有 Post.find().lean().populate(.. .)

我是否在 Post 模式上遗漏了一些东西,以便能够返回虚拟对象,或者我做错了什么?为什么在聚合操作中虚拟返回值“this.cover”为未定义?

谢谢!

4

2 回答 2

23

lean查询将原始MongoDB驱动程序响应作为普通js对象返回。因此,其中没有getters、或其他“猫鼬魔法”。有关更多信息,请参阅Api 文档settersvirtuals

查询的重点lean是尽可能快地返回您的对象。如果您需要virtuals- 使用普通的 Mongoose 查询。

至于聚合,它是 100% 的MongoDB特性,Mongoose 无法控制它。因此,当您aggregate从 Mongoose 调用时,它的工作方式与aggregateMongoDB控制台中相同。aggregate不能用 virtuals 操作,因为你的数据库中没有这样的字段。Mongoose 甚至不能根据你的模式转换你的聚合查询(就像它对findOneAndUpdate参数所做的那样),因为聚合在每一步都会改变文档的形状。有关更多信息,请参阅Mongoose API 文档MongoDB 文档

于 2013-08-22T14:18:54.063 回答
3

我找到了一个可以使用 mongoose-lean-virtuals 插件的解决方案

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

于 2019-04-30T16:54:19.940 回答