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

使用Mongoose的expires实现Token过期时移除Driver中关联的ObjectId引用

实现方案

该功能完全可以实现,首先需要注意一个核心坑点:Mongoose 的文档删除中间件仅在应用层主动调用删除方法时触发,MongoDB 后台 TTL 索引自动执行的删除操作不会触发这类中间件,因此不能直接用普通的 schema 中间件实现需求。

以下是两种可行的落地方案:

方案1:使用 MongoDB Change Stream 监听删除事件(推荐)

MongoDB 3.6及以上版本支持的 Change Stream 可以监听集合的所有数据变更事件,覆盖TTL自动删除、手动删除等所有删除场景,捕获事件后同步更新Driver文档即可。

实现代码:

const Token = mongoose.model('Token', tokenSchema);
const Driver = mongoose.model('Driver', driverSchema);

// 监听Token集合的变更事件
const tokenChangeStream = Token.watch();
tokenChangeStream.on('change', async (change) => {
  // 仅处理删除类型的变更
  if (change.operationType === 'delete') {
    const deletedTokenId = change.documentKey._id;
    // 同步清空所有关联Driver文档的token引用
    await Driver.updateMany(
      { token: deletedTokenId },
      { $unset: { token: "" } }
    );
  }
});

注意事项:

该方案要求你的MongoDB部署为副本集或分片集群模式,单机模式不支持Change Stream。

方案2:自定义定时任务清理过期Token(兼容单机MongoDB)

如果你使用的是单机MongoDB不支持Change Stream,可以放弃TTL索引的自动过期能力,自行实现定时任务扫描清理过期Token,清理时同步更新关联的Driver文档。

步骤1:修改TokenSchema移除expires配置

const tokenSchema: Schema = new Schema({
  token: { type: String, required: true },
  // 移除expires属性
  creationDate: { type: Date, required: true, default: Date.now },
});

步骤2:添加定时清理任务

以node-cron为例:

import * as cron from 'node-cron';

// 每分钟执行一次清理任务,和原TTL过期周期对齐
cron.schedule('* * * * *', async () => {
  const oneMinuteAgo = new Date(Date.now() - 60 * 1000);
  // 查询所有过期的Token
  const expiredTokens = await Token.find({ creationDate: { $lt: oneMinuteAgo } });
  const expiredTokenIds = expiredTokens.map(token => token._id);

  // 先清空关联Driver的token引用
  await Driver.updateMany(
    { token: { $in: expiredTokenIds } },
    { $unset: { token: "" } }
  );
  // 再删除过期Token
  await Token.deleteMany({ _id: { $in: expiredTokenIds } });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 10:54:04