如何在mongo db中进行分组和排序

时间:2016-06-28 14:54:45

标签: mongodb mongoose

我在mongodb中有一个带有mongoose架构的集合

var collection = new Schema({
  name : String,
  position : Number,
  category : String
});

collection.index({ category : 1, position : 1 }, { unique : true });

现在我想分批获取记录

它应该根据类别对所有记录进行分组,然后在每个类别(组)内,所有记录都应根据位置进行排序。

例如

我有以下收藏

[
  { name : 'Mr X', position : 34, category : 'U' },
  { name : 'Mr Y', position : 14, category : 'T' },
  { name : 'Mr G', position : 55, category : 'T' },
  { name : 'Mr I', position : 5, category : 'L' },
  { name : 'Mr D', position : 51, category : 'L' },
  { name : 'Mr P', position : 14, category : 'U' },
  { name : 'Mr P', position : 20, category : 'U' },
  { name : 'Mr E', position : 14, category : 'L' }
]

现在应该对此有效查询?

我正在尝试获取第3批(每批2条记录)

db.ask.aggregate([{
            $group : {
                _id : "$category"
            }
        }, {
            $sort : {
                position : 1
            }
        }, {
            $skip : 4
        }, {
            $limit : 2
        }
    ])

我期待输出:

[
  { name : 'Mr G', position : 55, category : 'T' },
  { name : 'Mr P', position : 14, category : 'U' }
]

但实际上没有。

如果获取所有记录(没有任何批次),预期输出应为

[
  { name : 'Mr I', position : 5, category : 'L' },
  { name : 'Mr E', position : 14, category : 'L' }
  { name : 'Mr D', position : 51, category : 'L' },
  { name : 'Mr Y', position : 14, category : 'T' },
  { name : 'Mr G', position : 55, category : 'T' },
  { name : 'Mr P', position : 14, category : 'U' },
  { name : 'Mr P', position : 20, category : 'U' },
  { name : 'Mr X', position : 34, category : 'U' },
]

编辑:我正在寻找一种灵活适应我不断变化的要求的查询。 如果我想带第一类T然后L然后U.?

所以我的预期输出(有限制和跳过)应该是

[
  { name : 'Mr I', position : 5, category : 'L' },
  { name : 'Mr P', position : 14, category : 'U' }
]

3 个答案:

答案 0 :(得分:0)

据我了解您的要求,您根本不想进行分组,只是希望按两个字段排序,然后或多或少地进行某种分页。
也就是说,通过以下聚合管道,我得到了您想要的结果。

db.ask.aggregate([
    { 
        $sort : {
            category : 1,
            position : 1 
        } 
    },
    {
        $project : {
            _id : 0,
            category : 1,
            position : 1,
            name : 1
        }
    },
    {  
        $skip : 4
    },
    {
        $limit : 2
    },
])

答案 1 :(得分:0)

好吧,你需要对复合键进行分组以获得所需的结果。

db.collection.aggregate([
 {$group : { _id : {category:"$category", position:"$position", name:"$name"}}}, 
 {$project:{_id:0, category:"$_id.category", name:"$_id.name", position:"$_id.position"}},
 {$sort : {"category" : 1, position:1} }, 
 {$skip : 4 }, 
 {$limit : 2 } 
])

这将打印:

{ 
    "category" : "T", 
    "name" : "Mr G", 
    "position" : 55.0
}
{ 
    "category" : "U", 
    "name" : "Mr P", 
    "position" : 14.0
}

答案 2 :(得分:0)

不需要分组和其他聚合阶段 只需按正确的字段排序

我们可以normal查询

db.codofoode.find()
.sort({
    category : 1,
    position : 1
}).skip(4).limit(2)

或汇总

db.codofoode.aggregate([
{
            $sort : {
              category:1,   position : 1
            }
        },

        {
            $skip : 4
        },
        {
            $limit : 2
        }])