我正在构建一个聊天机器人(使用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>
我有什么想法可以改善这个?如果您需要更多信息,请告诉我。谢谢。
答案 0 :(得分:3)
将字段last_active_date
添加到用户架构,并在每次收到消息时更新它。如果日期与今天匹配,那么您就完成了。如果不是,则需要更新字段并将记录添加到ActiveReports
集合中。
实际上,在我看来,你试图以一种使用关系数据库的方式使用Mongo。我的意思是,如果您只想将用户标记为活动状态,则ActiveReports
不需要。
如果您尝试构建某种报告以显示每位用户每天的应用使用情况,则可以在后台执行此操作。您可以拥有一个每天运行一次的工作(实际上,如果您有不同时区的用户并且您想要容忍他们的时间,您可能希望每天运行几次)。此作业将查询User
集合,并为ActiveReports
last_active_date
所找到的每个用户添加current_date
的记录。
答案 1 :(得分:1)
如果您要构建无状态服务器应用程序,则需要做的最小事情是拉出用户的记录以检查是否有效。
您可能会考虑让守护程序任务处理ActiveReports并在后台更新用户日期。这样,您只需处理一次这些记录,并且用户信息已准备就绪。此外,该进程可以具有状态,因此为每个记录更新每个用户可能更为理想。