1

我想向我的用户发送通知/提醒,提醒模式基本上是这样的

{
    user: 'number',
    time: {   //this is the time the event will occur
        type: Date,
        index: true
    },
    reminder: Number, //the number of minutes that user wants to be reminded before events occur
    date_reminder: { //this is basicaly time - reminder, 
        type: Date,
        index: true
    },
    text: String,
    eventId: Number,
    rrule: String, //the recurrence rrulle
    until: { //the date that the reccurence will end
        type: Date
    },
    title_event: String,
    calendarId: Number,
});

所以我做了一个 Cron 作业,每分钟在 mongodb 中搜索与此查询匹配的提醒:

{
    $or: [{
        rrule: {
            $ne: ""
        },
        $or: [{
            until: null //if until === null, its repeat forever
        }, {
            until: {
                $gte: new Date()
            }
        }],
    }, {
        date_reminder: new Date()
    }]
}

然后对于此查询返回的每个提醒,我需要检查生成的日期是否rrule与其reminder匹配new Date()

let now = new Date();
let remindersToSend = [];
reminders.forEach(reminder => {
    if (reminder.rrule === "") {
        //ts just a normal reminder that its date_reminder matches now 
        remindersToSend.push(reminder);
    } else {
        //this is a reccuring reminder, i need to check if some of its reccuring reminders matches now
        let myrrule = rrule.rrulestr(reminder.rrule);
        let repeatedReminders = myrrule.between(reminder.time, now);
        for (let i = 0; i < repeatedReminders.length; i++) {
            if (Math.round(moment.duration(moment(repeatedReminders[i])
                    .diff(moment(now))
                ).asMinutes()) === reminder.reminder) {
                //this repeatedDate matches now;
                remindersToSend.push(reminder);
                break;
            }
        }
    }
})

然后,在这一切之后,我可以安全地向所有人发送通知,remindersToSend但这给了我一个糟糕的表现,因为我每分钟都重复这个,我不知道我怎样才能做出更好的 mongo 查询来摆脱那些没有它的提醒重复时间匹配now

4

1 回答 1

1

您可以每小时/每天一次预先计算将在下一小时/每天发生的每个规则的所有即将发生的事件。将这些与您的提醒一起存储在数据库中。然后每分钟您只需要查询在当前分钟内有预先计算的事件的提醒。根据您的用例,您甚至可以预先计算所有提醒的出现。

于 2019-11-29T06:56:19.263 回答