MST

星途 面试题库

面试题:MongoDB复杂多条件匹配与性能优化

有一个大型的用户活动日志集合,每个文档记录了用户的'user_id'(用户ID)、'event_type'(事件类型)、'event_time'(事件发生时间)以及其他一些相关信息。现在需要查询出在过去一周内,特定用户组(例如user_id以'group1_'开头)发生的特定事件类型(如'login'和'purchase')的所有记录,并且查询操作要尽可能优化性能。请阐述详细的查询思路并写出对应的MongoDB查询语句以及可能涉及到的索引优化策略。
22.7万 热度难度
数据库MongoDB

知识考点

AI 面试

面试题答案

一键面试

查询思路

  1. 筛选时间范围:确定过去一周的时间范围,获取当前时间并减去一周时间,以此作为查询的时间下限。
  2. 匹配用户组:针对user_id进行筛选,只选择以group1_开头的用户。
  3. 匹配事件类型:筛选出event_typeloginpurchase的记录。

MongoDB查询语句

假设event_time字段存储的是日期类型:

// 获取当前日期
var currentDate = new Date(); 
// 计算一周前的日期
var oneWeekAgo = new Date(currentDate - 7 * 24 * 60 * 60 * 1000); 

db.user_activity_logs.find({
    user_id: { $regex: '^group1_' },
    event_type: { $in: ['login', 'purchase'] },
    event_time: { $gte: oneWeekAgo }
});

索引优化策略

  1. 复合索引:创建一个复合索引,将user_idevent_typeevent_time组合在一起。这样可以显著提升查询性能,因为查询条件中同时涉及这三个字段。
db.user_activity_logs.createIndex({ user_id: 1, event_type: 1, event_time: 1 });

索引顺序很重要,应按照查询条件中过滤性最强的字段在前的顺序排列。在这个场景下,user_id相对event_typeevent_time过滤性更强,所以放在最前面,其次是event_type,最后是event_time。 2. 覆盖索引:如果查询中只需要返回少数几个字段,可以考虑覆盖索引。即创建的索引包含查询需要返回的所有字段,这样MongoDB可以直接从索引中获取数据,而无需回表操作,进一步提升查询效率。但如果查询需要返回很多字段,覆盖索引可能会导致索引文件过大,反而影响性能,所以要权衡使用。