首页 > 解决方案 > mongodb删除超过一段时间但没有日期属性的文档

问题描述

我们正在尝试删除特定集合中超过 3 个月的文档。此集合上没有配置 TTL,这些文档上也没有单个日期/时间属性。无论如何,我怎样才能删除那些旧文件?有没有我可以运行的脚本来自动生成它?

谢谢

标签: mongodb

解决方案


假设您没有生成自己的_id字段,则ObjectId包含来自文档的时间戳:

12 字节的 ObjectId 值包括: ...

一个 4 字节的时间戳值,表示 ObjectId 的创建,以 Unix 纪元以来的秒数为单位

因此,如果您使用的是 Mongo 4.0+ 版,您可以使用$toDate ,匹配文档并使用$out覆盖当前集合

db.collection.aggregate([
  {
    $addFields: {
      shouldKeep: {
        $lt: [
          {
            $subtract: [
              "$$NOW",
              {
                $toDate: "$_id"
              }
            ]
          },
          7776000// 90 days in seconds
        ]
      }
    }
  },
  {
    $match: {
      shouldKeep: true
    }
  },
  {
    $project: {
      shouldKeep: 0
    }
  },
  {
    out: "curr_collection"
  }
])

蒙戈游乐场

请注意,这是一个 POC 示例,但这并不能处理很多问题,例如时区。确切的月份开始和结束(目前它计算 90 天后)等等。

更不用说$out在大型集合上使用包含很多开销。我的建议是对结果进行分页并在代码中执行此操作。例如nodejs,您可以使用 ObjectId 的getTimestamp方法,如下所示:(伪代码)

const someDocuments = [...];
for each document:
    const timestamp = document._id.getTimestamp();
    if (timestamp < 3 months ago) delete document.

现在在代码中,您可以相对轻松地处理时区、月份开始日期和规模问题。


推荐阅读