猫鼬填充查询以跳过/限制返回所有结果

时间:2019-03-07 20:55:02

标签: node.js mongodb mongoose mongodb-query

在小节点/快速应用中,我有以下方法:

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正常工作,所以问题可能出在我的架构上,但我不知道问题出在哪里。

我也尝试对虚拟字段添加注释,但是在limitsort未使用的地方。

我的猜测是它来自votes: [VoteSchema],因为这是我第一次使用它,但是我的老师建议使用ref 在非关系数据库中不建议使用。此外,为了将averageNote计算为一个虚拟字段,我别无选择。

编辑:仅使用votes: [{ ref: "Vote", type: mongoose.Schema.Types.ObjectId }]进行了尝试,但我仍然无法limitskip

节点版本:10.15.1

MongoDB版本:4.0.6

猫鼬版本:5.3.1

让我知道是否应该添加其他信息

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