39

我有一个学生数据库及其联系方式。我试图找出容纳最多学生的邮政编码。学生的文件看起来像这样......

{学生代码:'smi0001',名字:'bob',姓氏:'smith',邮编:2001}

我想我可以使用聚合框架来找出大多数学生的邮政编码,方法是......

db.students.aggregate({$project: { postcode: 1 }, $group: {_id: '$postcode', students: {$sum: 1}}})

这可以按预期工作(将邮政编码_id和每个邮政编码中的学生人数返回为“学生”,但是如果我添加$sort到管道中,它似乎会尝试按整个学生集合而不是$group操作结果进行排序。

我正在尝试的看起来像......

db.students.aggregate({$project: { postcode: 1 }, $group: {_id: '$postcode', students: {$sum: 1}}, $sort: {_id: -1}})

但它会返回整个集合并忽略$projectand $group...我错过了什么吗?我以为我只能按学生人数降序排序并返回第一项。提前感谢您的帮助。

4

2 回答 2

76

你几乎拥有它...

db.test.aggregate(
  {$group: {_id: '$postcode', students: {$sum: 1}}}, 
  {$sort: {_id: -1}}
);

给出(我添加了一些与您的样本匹配的测试数据):

{
  "result" : [
    {
        "_id" : 2003,
        "students" : 3
    },
    {
        "_id" : 2002,
        "students" : 1
    },
    {
        "_id" : 2001,
        "students" : 2
    }
  ],
  "ok" : 1
}

你对所有东西都有一个外在{},这引起了一些混乱。分组和排序在管道中没有作为单独的操作工作。

对于这种情况,您实际上并不需要该项目。

更新您可能想按“学生”排序,像这样,首先获得最大的邮政编码(按人口):

db.test.aggregate(
  {$group: {_id: '$postcode', students: {$sum: 1}}}, 
  {$sort: {students: -1}}
);
于 2012-09-16T23:24:46.870 回答
5

我认为您的语法略有错误。管道中的每个聚合操作都应该是它自己的文档。

db.students.aggregate( {$project: ...}, {$group: ...}, {$sort: ...} )

在你的情况下,它应该是:

db.students.aggregate(
    {$project: { postcode: 1 }}, 
    {$group: {_id: '$postcode', students: {$sum: 1}}}, 
    {$sort: {students: -1}}
)

我已经根据您的架构在样本集合上对其进行了测试,它适用于我,按学生人数降序对分组的邮政编码进行排序。

于 2012-09-16T23:39:16.670 回答