You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

额外注意事项

  1. 确保你的MongoDB版本在3.2及以上,这个版本才支持带partialFilterExpression的TTL索引。
  2. 修改索引后,需要重启应用让Mongoose重建索引;如果之前错误的createdAt索引已经存在,需要手动删除:
    在MongoDB Shell中执行:
    db.donations.dropIndex("createdAt_1")
    

内容的提问来源于stack exchange,提问作者leonardo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 11:35:59