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

这是我的应用程序中的一种情况:如果用户A一天与机器人聊天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集合,并为找到ActiveReports的每个用户向last_active_date添加记录。

关于javascript - 提高重复Mongo数据库访问任务的性能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48068642/

10-13 02:54