【问题标题】:mongoDB Time-field Trigger?mongoDB时域触发器?
【发布时间】:2019-01-21 16:46:23
【问题描述】:

我有一个与 mongoDb 实例集成的基于节点的后端。数据库有一组日历事件,每个事件都有一个唯一的日期时间字段。我正在考虑在设定时间前 15 分钟执行提醒功能的最佳方式。

我想出的唯一想法是始终使用 setInterval 查询数据库,然后运行该函数。有没有更好的办法?

【问题讨论】:

  • 事件是动态的(即date-time 字段可以更改)还是静态的?
  • 它们可以改变,但大多数是静态的。
  • 您不考虑使用任何延迟队列解决方案吗?因为这是延迟队列的经典问题。您将获得更好的解决方案,而不是始终如一地查询 mongodb,您只需在插入日历事件集合时推送到延迟队列,并正确计算延迟时间。
  • 你也可以试试cron-job 然后每15分钟运行一次

标签: node.js mongodb


【解决方案1】:

显然setInterval 和拉取数据库似乎是最简单的方法。下面的解决方案可以被视为数据库启动这些计划事件的替代方案,因此您将获得 push 而不是 pull 方法。

假设您有一个简单的集合 scheduledEvents,其中包含一个 ISODate 类型的字段 scheduledAt,例如:

{ "_id" : ObjectId("5c457cb554651d56ffe0c759"), "scheduledAt" : ISODate("2019-01-21T08:03:01.129Z") }

然后您可以在该集合上创建TTL index。基本上这个想法是当 scheduledAt 成为过去的日期时,MongoDB 数据库服务器将定期删除这些文档。

db.scheduledEvents.createIndex( { "scheduledAt": 1 }, { expireAfterSeconds: 30} )

幕后有一个在数据库服务器上运行的计划作业,它查询并删除所有这些文档。文件不会立即被删除 - 会有一点延迟,但您应该可以接受。

现在您有了一种调度机制,因此您需要做的就是从您的代码中订阅这些事件。为此,您可以利用Change Streams

要使用它们,您必须将数据库作为副本集运行(可以是 standalone replica set)。然后在您的应用程序代码中,您可以使用以下代码订阅 scheduledEvents 集合:

const changeStreamCursor = db.scheduledEvents.watch();

function pollStream(cursor) {
    while (!cursor.isExhausted()) {
        if (cursor.hasNext()) {
            var change = cursor.next();
            if(change.operationType === "delete"){
                // your logic goes here
            }
        }
    }
    pollStream(cursor);
}

pollStream(changeStreamCursor);

显然scheduledEvents 集合可以包含与您的业务逻辑相关的其他字段,并且可以在您的更改流侦听器中访问这些字段。

【讨论】:

  • 这种方法需要额外的努力。它要求 15 分钟提醒,因此您不能将 scheduleAt 用于 TTL 索引。此外,为此,必须删除文档以创建 oplog 事件。您必须在活动开始前 15 分钟设置时间表并删除活动以使 TTL 正常工作。
【解决方案2】:

从数据库轮询是最简单的方法。如果您担心避免过于频繁地查询数据库,您可以尝试以下方法。

  1. 启动基于节点的后端。
  2. 寻找未来的第一个日历事件。
  3. 使用 setInterval() 安排下一次提醒。
  4. 提醒事件触发后,从#2开始重复。

如果您的事件有更新,您可以使用 MongoDB 的 Change Streams 来监控更改。更新日历事件后,将其与下一个提醒事件进行比较,如果它在下一个日历提醒之前,则替换下一个提醒。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-15
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多