mongoDB时间字段触发器?

时间:2019-01-15 14:38:33

标签: node.js mongodb

我有一个与mongoDb实例集成的基于节点的后端。 DB具有日历事件的集合,每个日历事件都有一个唯一的日期时间字段。我正在尝试考虑在设置时间前15分钟执行提醒功能的最佳方法。

我想出的唯一想法是用setInterval一致地查询数据库,然后运行该函数。有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

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

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

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

希望这会有所帮助。

答案 1 :(得分:0)

显然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集合可以包含与您的业务逻辑相关的其他字段,并且可以在变更流侦听器中访问这些字段。