MongoDB中find与aggregate的查询区别及按ID日期查询的最优选择
两条MongoDB查询语句的核心区别
- 返回字段不同
示例中的aggregate查询通过前置$project阶段,指定了仅返回_id、info.created_date、info.store_id、info.store_name4个字段;而find查询没有指定投影参数,默认会返回所有匹配文档的全部字段。 - 执行顺序不同
示例中的aggregate执行顺序是「先裁剪所有文档的字段,再按条件过滤」,这种写法无法利用过滤字段的索引,会触发全表扫描;而find默认执行顺序是「先按条件过滤匹配文档,再处理投影(如果有配置)」,天然符合索引命中的规则。 - 能力边界不同
aggregate是管道型查询,支持多阶段复杂处理(分组统计、多集合关联、字段计算、数据转换等),适合复杂数据分析场景;find是基础查询接口,仅支持简单的过滤、投影、排序、分页操作,适合常规数据查询场景。 - 性能表现不同(针对本次示例写法)
示例的aggregate写法因为先投影后过滤,无法命中info.store_id和info.created_date的联合索引,扫描数据量远大于find,性能差距明显。
该场景下的最优查询方式
针对仅按store_id、created_date筛选数据的简单场景,优先选择find查询,原因如下:
- 语法更简洁易懂,维护成本更低;
- 性能更稳定:
find的过滤条件可以直接命中索引,不需要额外的管道调度开销。如果需要和示例aggregate一样仅返回指定字段,只需要给find加第二个投影参数即可,写法如下:
db.getCollection('stock_records').find( { 'info.store_id':'563dcf3465512285781608802a', 'info.created_date':{ $gt:ISODate('2021-07-18T21:07:42.313+00:00')} }, { "info.created_date": 1, "info.store_id": 1, "info.store_name": 1, "_id": 1 } )
上述调整后的find查询和把$match放到$project之前的优化版aggregate性能基本一致,但find写法更简洁,没有必要引入聚合管道。
内容的提问来源于stack exchange,提问作者vijay
相关产品推荐
相关产品推荐

