一种使一个集合中的特定文档过期并在到期时将它们添加到另一个集合的好方法

A good way to expire specific documents in one collection and add them to another collection on expiry

我正在使用 Nodejs 和 MongoDB 驱动程序。

两部分问题

  1. 我有一个名为 openOffers 的集合,我希望它在到达时间 closeOfferAt 时过期。我知道 MongoDB 提供 TTL,expireAtexpireAfterSeconds。但是,当我使用这些时,相同的 TTL 将应用于特定集合中的所有文档。我不确定我这样做是否正确。我想要文档级别自定义到期。任何语法都可能非常有用! openOffers
  2. 中的文档
{
 "_id":"12345",
 "data": {...},
 "closeOfferAt" : "2022-02-21T23:22:34.023Z"
}
  1. 我想将这些过期文档推送到另一个集合openOfferLog。这样我就可以保留文档供以后分析。

当前方法: 我还没有想出一种方法来为 openOffers 中的每个文档设置自定义 TTL。但是,我目前将文档插入到 openOffersopenOffersLog 中,openOffers 中的任何数据更改都必须单独传播到 openOffersLog 以确保一致性。我想必须有更好的可扩展方法。

EDIT-1:

我正在寻找可用于上述用例的语法逻辑。如果当前 MongoDB 驱动程序无法实现,我正在寻找可以试验的 NodeJS 代码的替代解决方案。我是 NodeJS 和 MongoDB 的新手——所以任何支持该解决方案的推理都将非常有用。

不要让您的应用程序逻辑依赖于 TTL 索引。

在您的应用程序中,您应该有一些运行周期性任务的调度程序,其中一些会将完成的报价移动到其他集合并从原始集合中删除,即使是批量删除也不需要设置 TTL 索引。

为了保持一致性,没有比单一事实来源更好的方法了,所以如果可以的话,避免删除,只更改一些状态标志和时间戳。

TTL 索引的一个很好的用途是在相对较长的时间(例如一个月或更长时间)后自动清除旧数据。这样可以控制 collection/indexes 大小。

TTL索引有两种实现方式。

  • 一定时间后删除 - 这是你已经实现的
  • 在特定时钟时间删除 - 有关详细答案,您可以访问 MongoDB Docs

所以第二个选项符合你的期望,

  1. 只需在创建索引时在 expireAfterSeconds 字段中设置 0(零),
db.collection.createIndex({ "closeOfferAt": 1 }, { expireAfterSeconds: 0 })
  1. 只需在插入文档时在 closeOfferAt 中设置到期日期,这将在特定时间戳删除文档。
db.collection.insert({
    "_id":"12345",
    "data": {...},
    "closeOfferAt" : ISODate("2022-02-23T06:14:15.840Z")
})