提高重复 Mongo 数据库访问任务的性能



我正在构建一个聊天机器人(使用MeteorJS/NodeJS),每天与大约2,000个活跃用户互动。我知道每天与机器人聊天的确切人数,因为我将用户的活动信息存储在名为ActiveReportsMongoDB集合中。

这是我的应用中的一个场景:如果用户在一天内与机器人聊天100 次(= 100 条消息),将执行以下步骤:

- receive message from users   
- check if this user is marked as 'active' today ?  // high cost
- if yes => don't do anything   
- if no => mark this user as 'active' for today  

如您所见,对每条消息执行步骤 2。此步骤在技术上等效于访问 ActiveReports 集合,找到时间戳 = 今天,用户 = 用户 A 的集合。由于ActiveReports馆藏有很多文档(大约 100,000 个文档),这是一项相当繁重的任务。这会对应用的性能产生负面影响。

注 1:这是ActiveReports集合架构:

SimpleSchema({
// _id must be set `type` as String and `optional` as true
//  to avoid ObjectId(_id) after insert in to database
_id: {
type: String,
optional: true,
},
date: {
type: Date,  // Note: date is always the timestamp of the start of the current day, so 1AM timestamp and 9PM timestamp will be changed to 0AM timestamp (before the insert)
},
userId: {
type: String,
},
});

这就是我为这个集合编制索引的方式:

ActiveReports._ensureIndex({ date: 1, userId: 1 }, { unique: true });

注 2:用户在一天内处于活动状态,表示他当天至少与机器人交互 1 次(例如向机器人发送消息)。

任何想法如何改善这一点?如果您需要更多信息,请告诉我。谢谢。

将字段last_active_date添加到用户架构,并在每次收到消息时更新它。如果日期与今天匹配,您就完成了。如果不是,则需要更新字段并将记录添加到集合ActiveReports

实际上,在我看来,您正在尝试以使用关系数据库的方式在这里使用Mongo。我的意思是,如果您只想将用户标记为活动,则无需ActiveReports

如果您尝试构建某种报告来显示每个用户每天的应用程序使用情况,则可以在后台执行此操作。你可以有一个每天运行一次的作业(实际上,如果你的用户在不同的时区,并且你想容忍他们的时间,你可能希望每天运行几次)。此作业将查询User集合,并为找到last_active_datecurrent_date的每个用户向ActiveReports添加记录。

如果您正在构建无状态服务器应用程序,您至少需要做的是拉取用户的记录以检查活动状态。

您可以考虑让守护程序任务处理活动报告并在后台更新用户日期。 这样,您只需处理一次这些记录,用户信息就可以使用了。 此外,该进程可以具有状态,因此更新每个用户每条记录的最佳选择。

最新更新