我正在构建一个聊天机器人(使用MeteorJS/NodeJS
),每天与大约2,000位活跃用户进行交互。我知道每天与机器人聊天的确切人数,因为我将用户的活动信息存储在称为MongoDB
的ActiveReports
集合中。
这是我的应用程序中的一种情况:如果用户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/