mongodb ttl索引依赖后台线程周期扫描,仅支持date类型字段的单字段索引,expireafterseconds:0表示精确过期;azure cosmos db强制用\_ts字段且不支持自定义时间字段;ttl非实时,不可用于强时效业务逻辑。

MongoDB 的 TTL 索引不是“设了就立刻删”,它依赖后台线程周期性扫描,且对字段类型、索引结构、时钟语义有硬性要求。配置错一步,文档就永远不会过期。
必须用日期类型字段建单字段索引
TTL 索引只接受 Date 类型(或含 Date 的数组)作为索引键,不支持字符串、数字、ISODate 字符串字面量等伪日期值。复合索引(如 {"createdAt": 1, "status": 1})直接忽略 expireAfterSeconds 选项,不会触发任何清理。
- ✅ 正确:文档中
expiresAt字段是Date实例,索引为db.logs.createIndex({"expiresAt": 1}, {expireAfterSeconds: 0}) - ❌ 错误:
"expiresAt": "2026-09-08T00:00:00Z"(字符串)、"expiresAt": 1725753600000(毫秒数)、db.logs.createIndex({"expiresAt": 1, "type": 1}, {expireAfterSeconds: 3600}) - ⚠️ 注意:
expireAfterSeconds: 0表示“在expiresAt时间点精确过期”,不是“立即删除”;负值无效,会被忽略
Azure Cosmos DB for MongoDB 用 _ts 而非业务时间字段
Azure Cosmos DB for MongoDB 不允许你用自定义时间字段做 TTL —— 它强制使用系统字段 _ts(单位:秒级 Unix 时间戳,只读,不可写入)。这意味着你无法按“绝对过期时间”控制,只能按“最后修改后多少秒过期”来设定。
一款AI工具,主要用于一款基于 Rust 的快速无头浏览器自动化命令行工具(CLI),支持 Node.js 回退机制,可使 AI agent 通过结构化命令实现页面导航、点击、输入及截图,适合需要提升相关任务效率的用户。
- ✅ 正确:
db.sessions.createIndex({"_ts": 1}, {expireAfterSeconds: 1800})→ 30 分钟未更新的会话自动删除 - ❌ 错误:试图对
validUntil字段建 TTL 索引,或向_ts写入值(会失败) - ⚠️ 注意:
_ts每次写操作自动更新,但无法用于“指定某天某时过期”的场景;若需绝对时间,得用应用层定时任务 + 普通查询 +deleteMany()
文档级 TTL(ttl 字段)仅限 Azure Cosmos DB,标准 MongoDB 不支持
标准 MongoDB(包括 Atlas、本地部署)**没有**文档级 ttl 字段机制。所谓“每个文档单独设过期时间”,在原生 MongoDB 中只能通过让每个文档的 TTL 字段(如 expiresAt)取不同 Date 值来实现,而索引仍是统一的。
- ✅ Azure Cosmos DB 支持:
{"_id": "...", "ttl": 3600}+_ts索引 → 该文档 1 小时后过期(覆盖集合默认值) - ❌ 标准 MongoDB:
{"_id": "...", "ttl": 3600}完全无意义,ttl字段只是普通字段,不被 TTL 机制识别 - ⚠️ 注意:Azure Cosmos DB 的
ttl必须是int32或可转为int32的整数,double必须无小数位,否则静默失效
TTL 清理不是实时的,也不能靠它做强时效逻辑
mongod 的 TTL 后台线程默认每 60 秒扫描一次,且是单线程串行处理所有 TTL 索引。这意味着:刚过期的文档可能最多延迟 60 秒才从查询结果中消失;高并发写入时,过期文档堆积可能导致内存/磁盘压力上升;删除操作不释放磁盘空间,只是标记为可复用。
- ✅ 可接受场景:日志保留 7 天、会话超时 30 分钟、缓存类数据衰减
- ❌ 不可依赖场景:支付订单 15 分钟未支付自动关单(需结合应用层定时任务或 Change Stream 监听)
- ⚠️ 关键提醒:不要用
find()查询结果判断“是否已过期”,应始终以 TTL 字段值 + 当前时间做应用层校验;TTL 是辅助清理手段,不是业务时效保障机制










