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

时间:2018-01-02 22:21:41

标签: javascript node.js mongodb performance meteor

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

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

ActiveReports

如您所见,每个消息都会执行第2步。此步骤在技术上等同于访问ActiveReports集合,找到时间戳=今天,用户=用户A 的集合。由于- 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 集合包含大量文档(大约100,000个文档),因此这是一项相当繁重的任务。这会对应用程序的性能产生负面影响。

注1:这是ActiveReports集合架构:

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,
  },
});

注2:用户有效一天意味着他与机器人交互至少一次(例如向机器人发送消息)。< / p>

我有什么想法可以改善这个?如果您需要更多信息,请告诉我。谢谢。

2 个答案:

答案 0 :(得分:3)

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

实际上,在我看来,你试图以一种使用关系数据库的方式使用Mongo。我的意思是,如果您只想将用户标记为活动状态,则ActiveReports不需要。

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

答案 1 :(得分:1)

如果您要构建无状态服务器应用程序,则需要做的最小事情是拉出用户的记录以检查是否有效。

您可能会考虑让守护程序任务处理ActiveReports并在后台更新用户日期。这样,您只需处理一次这些记录,并且用户信息已准备就绪。此外,该进程可以具有状态,因此为每个记录更新每个用户可能更为理想。