Mongoose TTL索引异常:paid为true时文档仍自动过期的求助
问题解决:Mongoose TTL索引错误删除已付费文档
你的问题根源在于TTL索引指定的字段与Schema中实际存在的字段不匹配:
你创建索引时用了createdAt,但你的Schema里定义的时间字段是iat。MongoDB找不到createdAt字段时,会将所有文档的该字段视为null,而TTL索引会自动删除所有null值的文档,完全忽略了partialFilterExpression的过滤条件。
修复后的代码
将索引的目标字段改为iat,并保留正确的过滤条件:
const mongoose = require('mongoose'); const donationSchema = new mongoose.Schema({ user: { type: mongoose.SchemaTypes.ObjectId, ref: 'User' }, ngo: { type: mongoose.SchemaTypes.ObjectId, ref: 'Ngo', required: true }, type: { type: String, default: 'ads', required: true }, amount: { type: Number }, iat: { type: Date, default: Date.now }, paid: { type: Boolean, default: false, }, orderID: { type: String }, }); // 修改索引目标字段为iat,保留partial过滤条件 donationSchema.index( { iat: 1 }, { expireAfterSeconds: 60, partialFilterExpression: { paid: false }, }, ); function autoPopulateChildren(next) { this.populate('user', 'fullName level avatar country -_id'); next(); } donationSchema.pre('find', autoPopulateChildren); module.exports = new mongoose.model('Donation', donationSchema);
额外注意事项
- 确保你的MongoDB版本在3.2及以上,这个版本才支持带
partialFilterExpression的TTL索引。 - 修改索引后,需要重启应用让Mongoose重建索引;如果之前错误的
createdAt索引已经存在,需要手动删除:
在MongoDB Shell中执行:db.donations.dropIndex("createdAt_1")
内容的提问来源于stack exchange,提问作者leonardo
相关产品推荐
相关产品推荐

