面试题答案
一键面试查询思路
- 筛选时间范围:确定过去一周的时间范围,获取当前时间并减去一周时间,以此作为查询的时间下限。
- 匹配用户组:针对
user_id
进行筛选,只选择以group1_
开头的用户。 - 匹配事件类型:筛选出
event_type
为login
和purchase
的记录。
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 }
});
索引优化策略
- 复合索引:创建一个复合索引,将
user_id
、event_type
和event_time
组合在一起。这样可以显著提升查询性能,因为查询条件中同时涉及这三个字段。
db.user_activity_logs.createIndex({ user_id: 1, event_type: 1, event_time: 1 });
索引顺序很重要,应按照查询条件中过滤性最强的字段在前的顺序排列。在这个场景下,user_id
相对event_type
和event_time
过滤性更强,所以放在最前面,其次是event_type
,最后是event_time
。
2. 覆盖索引:如果查询中只需要返回少数几个字段,可以考虑覆盖索引。即创建的索引包含查询需要返回的所有字段,这样MongoDB可以直接从索引中获取数据,而无需回表操作,进一步提升查询效率。但如果查询需要返回很多字段,覆盖索引可能会导致索引文件过大,反而影响性能,所以要权衡使用。