MongoDB分组后Skip与Limit失效问题及解决方法
MongoDB分组后分页问题解决方案
你的当前聚合查询存在逻辑偏差:先通过$match过滤出所有name=MyProject的项目,再用$group按status分组,每个组会包含对应状态下的全部项目。之后的$skip和$limit是对「分组生成的组文档」分页,而非对「项目」分页。如果你的数据中status的取值数量很少(比如只有1种状态),分组后只会生成1个组,自然会返回所有项目。
根据不同需求,提供以下解决方案:
场景1:分页获取项目,同时按status分组展示当前页项目
若需求是每次获取10个项目,再将这10个项目按status分组展示,需先对项目分页,再执行分组:
db.myCollection.aggregate([ { "$match": { "name": "MyProject" } }, // 项目分页:第N页的skip值为 (N-1)*10 { "$skip": 0 }, { "$limit": 10 }, { "$group": { "_id": { "status": { "$ifNull": ["$data.status", null] } }, "records": { "$push": "$$ROOT" } }} ])
场景2:每个status组返回指定数量的项目
若需求是保留所有status分组,但每个组仅返回前10个项目,可在分组后用$slice截取每组的项目列表:
db.myCollection.aggregate([ { "$match": { "name": "MyProject" } }, { "$group": { "_id": { "status": { "$ifNull": ["$data.status", null] } }, "records": { "$push": "$$ROOT" } }}, { "$project": { "status": "$_id.status", "records": { "$slice": ["$records", 0, 10] }, "_id": 0 }} ])
场景3:对分组后的组进行分页
若数据中存在大量不同的status值,需要分页获取这些组(比如每次返回10个不同的status组),原查询逻辑是有效的。如果返回所有项目,说明你的数据中status取值数量不足10个,此时$limit 10会返回全部组,每个组包含对应状态下的所有项目,可先确认数据的status分布情况。
内容的提问来源于stack exchange,提问作者Gohar Vardanyan
相关产品推荐
相关产品推荐

