在小节点/快速应用中,我有以下方法:
async getAll(req, res) {
const movies = await movieModel
.find()
.populate({path: 'genres', select: 'name'})
.skip(0)
.limit(15);
return res.send(movies);
};
具有以下架构:
const MovieSchema = new mongoose.Schema({
externalId: { required: true, type: Number },
title: { required: true, type: String },
genres: [{ ref: "Genre", type: mongoose.Schema.Types.ObjectId }],
releaseDate: {type: Date},
originalLanguage: {type : String},
originalTitle: {type : String},
posterPath: {type : String},
backdropPath: {type : String},
overview: {type: String},
comments: [{ ref: "Comment", type: mongoose.Schema.Types.ObjectId }],
votes: [VoteSchema]
}, {timestamps: true}
});
MovieSchema.virtual("averageNote").get(function () {
let avg = 0;
if (this.votes.length == 0) {
return '-';
}
this.votes.forEach(vote => {
avg += vote.note;
});
avg = avg / this.votes.length;
return avg.toFixed(2);
});
MovieSchema.set("toJSON", {
transform: (doc, ret) => {
ret.id = ret._id;
delete ret._id;
delete ret.__v;
},
virtuals: true,
getters: true
});
但是查询总是返回所有文档条目。
我还尝试在查询末尾添加exec()
或添加.populate({path: 'genres', select: 'name', options: {skip: 0, limit: 15} })
但没有结果。
我尝试了另一个更简单的架构,并且skip
/ limit
正常工作,所以问题可能出在我的架构上,但我不知道问题出在哪里。
我也尝试对虚拟字段添加注释,但是在limit
和sort
未使用的地方。
我的猜测是它来自votes: [VoteSchema]
,因为这是我第一次使用它,但是我的老师建议使用ref
在非关系数据库中不建议使用。此外,为了将averageNote计算为一个虚拟字段,我别无选择。
编辑:仅使用votes: [{ ref: "Vote", type: mongoose.Schema.Types.ObjectId }]
进行了尝试,但我仍然无法limit
或skip
节点版本:10.15.1
MongoDB版本:4.0.6
猫鼬版本:5.3.1
让我知道是否应该添加其他信息
答案 0 :(得分:1)
这实际上是关于.populate()
实际工作方式以及为什么“链接方法” 的顺序很重要的原因。但简单来说:
const movies = await movieModel
.find()
.skip(0)
.limit(15)
.populate({path: 'genres', select: 'name'}) // alternately .populate('genres','name')
.exec()
问题是.populate()
实际上只是对数据库运行另一个查询以“模拟” 和 join 。这实际上与原始.find()
无关,因为所有populate()
所做的只是从查询中获取结果并使用某些值来“查找” < / em>使用另一个查询在另一个集合中的文档。重要的是,结果排在最后。
另一边的.skip()
和.limit()
是光标修饰符,并且直接属于基础MongoDB驱动程序。这些属于{em> .find()
,因此它们必须按顺序
构建器的MongoDB驱动程序部分是宽容的:
.find().limit(15).skip(0)
由于“一次全部”传递选项的方式,
也是可以接受的,但是将其视为skip
然后 limit
。
总体而言,{<1>}方法 必须是任何光标修饰符之后链上的 最后 em>,例如populate()
或limit()
。