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

Mongoose中如何调整TTL的expiresAfterSeconds时长并保留timestamps?

URL模型TTL索引问题解决指南

问题背景

我正在开发一个简易应用,使用Mongoose定义了如下URL模型:

import mongoose from "mongoose";

const urlSchema = new mongoose.Schema(
  {
    originalUrl: { type: String, required: true },
    longUrl: { type: String, required: true, unique: true },
    shortUrl: { type: String, required: true, unique: true },
    click: {
      type: Number,
      default: 0,
    },
  },
  { timestamps: true }
);

export const Url = mongoose.model("Url", urlSchema);

现在遇到的问题是:创建模型实例后,文档会在2分钟后自动删除。查询MongoDB索引发现存在一个基于createdAt字段的TTL索引,其expiresAfterSeconds被设为120。我希望将自动删除时长调整为3天,或者在保留createdAt、updatedAt字段的前提下完全禁用该TTL自动删除机制。同时想了解为何启用timestamps: true会自动生成该TTL索引,以及如何避免此类问题。

执行db.urls.getIndexes()返回的索引信息如下:

[
  { v: 2, key: { _id: 1 }, name: '_id_' },
  {
    v: 2,
    key: { longUrl: 1 },
    name: 'longUrl_1',
    background: true,
    unique: true
  },
  {
    v: 2,
    key: { shortUrl: 1 },
    name: 'shortUrl_1',
    background: true,
    unique: true
  },
  {
    v: 2,
    key: { createdAt: 1 },
    name: 'createdAt_1',
    background: true,
    expireAfterSeconds: 120
  }
]

解决方案

调整TTL自动删除时长为3天

先删除现有TTL索引,再创建新的3天过期索引:

  1. 在MongoDB shell执行删除命令:
db.urls.dropIndex("createdAt_1")
  1. 创建3天有效期的TTL索引(3天=259200秒):
db.urls.createIndex({ createdAt: 1 }, { expireAfterSeconds: 259200 })

如果想在Mongoose模型中直接定义,可在schema里为createdAt字段添加expires配置(需先删除旧索引):

const urlSchema = new mongoose.Schema(
  {
    originalUrl: { type: String, required: true },
    longUrl: { type: String, required: true, unique: true },
    shortUrl: { type: String, required: true, unique: true },
    click: { type: Number, default: 0 },
    createdAt: { type: Date, expires: '3d' } // 设置3天后过期
  },
  { timestamps: true }
);

完全禁用TTL自动删除

直接删除已有的TTL索引即可,timestamps: true生成的createdAt和updatedAt字段不受影响:

db.urls.dropIndex("createdAt_1")

执行后,新创建的文档不会再被自动删除,时间字段仍正常生成和更新。

为什么timestamps: true会出现TTL索引?

Mongoose的timestamps: true仅负责自动添加和更新createdAt、updatedAt字段,不会自动创建TTL索引。出现这个问题的原因通常是:

  • 之前的模型版本中给createdAt配置过expires属性,同步到数据库后未清理;
  • 手动在数据库中创建过该TTL索引;
  • 项目中的数据库初始化脚本自动生成了这个索引。

避免此类问题的方法

  • 模型变更后,用db.collection.getIndexes()检查索引是否符合预期;
  • 仅在需要自动删除文档时,才给字段添加expires配置;
  • 数据库初始化脚本要明确索引创建逻辑,避免意外生成不必要的索引;
  • 团队协作时同步模型和索引的变更记录,防止操作冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 16:37:20