我目前使用通行证进行身份验证,使用 mongodb 来存储用户信息。
然而,我一直试图限制用户的每日发帖限制。我想在 User Schema 中设置一个类似每日发帖限制的字段,每当用户发帖时,我都会扣除计数。
const user = new mongoose.Schema({
githubId: {
required: true,
type: String,
},
username: {
required: true,
type: String,
},
dailyPostLimit: {
type: Number,
default: 3,
},
});
但是我不确定是否有办法每天将该计数重置为默认值 (3)。 CRON 任务适合这里还是有更简单的方法来完成此任务?
答案 0 :(得分:1)
cron 任务很适合重置这样的值,缓存这样的值是解决这个问题的合理方法。但是,请记住,您正在缓存此值,缓存失效是一个难题,通常会导致错误和额外的复杂性。
我的第一直觉不是缓存,而是计算每次的帖子数量。这是一些伪代码:
const count = await posts.count({userId, createdAt: {$gte: startOfDay}});
// alternative: const count = await posts.count({userId, _id: {$gte: startofDayConvertedToMongoId});
if (count > 3) throw new Error("no more posts for you");
await posts.create(newPost)
(注意:如果您担心竞争条件,任何您选择的解决方案都需要检查交易中的计数)
如果您有一个以 {userId: 1, createdAt: 1}
开头的索引,或者您使用 _id
代替 {userId: 1, _id: 1}
(假设您不允许创建客户端 _id
),这些查询将非常便宜,而且它们很难不同步。
即使您决定缓存这些创建值,我还是建议将它们从用户的集合中缓存起来,以使您的集合更加集中。您可以创建一个 post_count
集合,然后仅更新这些计数的缓存集合:post_count.updateOne({userId, day}, {$incr: {count: 1}, $setOnInsert: {day, userId, count: 0}}, {upsert: true});
。这种方法的一个好处是您可以使用 ttl
上的 day
索引让 mongo 在过期后自动删除此集合中的旧文档。
答案 1 :(得分:0)
既然你使用的是 MongoDB,我建议,
user
模型上的 updateMany 函数用于重置 dailyPostLimit
字段。