首页 > 解决方案 > 如何对帖子进行排序、索引和分页 mongodb-mongoose

问题描述

我有以下 postSchema 并希望根据 updatedAt 字段获取数据。当人们发表评论时,我将 numberofreply 增加一并且它的 updatedAt 被更新。我应该如何获取无限滚动的数据,我应该为此操作使用索引?

const postScheme = mongoose.Schema(
    {
        post: {
            type: String,
            trim: true,
        },
        numberOfReply: {
            type: Number,
            default: 0
        },
        owner: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'User'
        },
        hasImage: {
            type: Boolean,
        },
        image: {
            type: String,
            trim: true
        },
    },
    {timestamps: true}
)

这是我用来获取第一页的

Post.Post.find({}).sort({'updatedAt': -1}).limit(10).populate('owner').populate('coin').exec(function (err, posts) {
    res.send(posts)
})

这是无限滚动的

Post.Post.find({isCoin: true, updatedAt: {$lt: req.body.last}}).sort({'updatedAt': -1}).populate('owner').limit(
    10).exec(function (err, posts) {
    res.send(posts)
})

标签: node.jsmongodbmongooseindexingpagination

解决方案


,语法是 Mongo 对数据进行分页的方式limitskip所以你得到了解决,从代码的角度来看,你不能真正改变任何东西来更好地工作。

我应该为此操作使用索引吗

绝对是的,索引是使此操作高效的方法。否则 Mongo 将对每个分页进行一次集合扫描,这是非常低效的。

那么你应该建立什么样的索引呢?好吧,您想构建一个复合索引,该索引将允许查询同时满足查询和排序条件,在您的情况下,它位于isCoinandupdateAt字段上,如下所示:

db.collection.createIndex( { isCoin: 1, updateAt: -1 } )

您可以进行一些改进以使索引更高效(对于此特定查询):

  1. 考虑将索引创建为稀疏索引,这只会索引包含两个字段的文档,显然如果数据不包含此选项,您可以忽略它。

  2. 这个有一些警告,但部分索引是为这种情况设计的,通过索引数据的较小子集来提高查询性能。在您的情况下,您可以添加此选项

{ partialFilterExpression: { isCoin: true } }

话虽如此,这将限制您对其他查询的索引使用,因此它可能不是您的最终选择。


推荐阅读