MongoDB按字段分组,计数并降序排序

12

我有以下的文档结构:

{
    ..
    "mainsubject" : {
        "code": 2768,
        "name": "Abc"
    }
}
现在我需要一个所有主题代码和它们被使用的次数的列表。
用SQL的话,我会像这样做:
SELECT mainsubject_code, COUNT(*) AS 'count'
FROM products
GROUP BY mainsubject_code
ORDER BY count

我已经能够将其分组并计数:

db.products.aggregate([
    {"$group" : {_id:"$mainsubject.code", count:{$sum:1}}}
]);

但是如何对它进行排序呢?

db.coll.aggregate([
  {
     $group: { 
        _id: "$mainsubject.code", 
        countA: { $sum: 1}
     }
  },
  {
    $sort:{$mainsubject.code:1}
  }
])

没起作用?


3
分组后,您的文档结构会发生变化。字段"mainsubject.code"不再存在,被"_id"替代。请尝试添加这个**$sort**阶段:{$sort: {_id: 1}} - felix
2
像命令行上的管道 | 一样思考“pipline”。在每个分离点,唯一的“输入”是先前的“输出”。因此,在 $group 之后,只有 _idcountA 是属性。 - Neil Lunn
啊,好的!现在我明白了。这就像在SQL中使用子查询或在Linux命令行上使用管道一样。 - bernhardh
3个回答

9

从您的SQL查询来看,您想按计数排序。因此,在Mongo查询中,您也应该将 countA 作为排序字段。

db.coll.aggregate([
  {
     $group: { 
        _id: "$mainsubject.code", 
        countA: { $sum: 1}
     }
  },
  {
    $sort:{'countA':1}
  }
])

1

使用Sort By Count ($sortByCount) 基于指定表达式的值对传入的文档进行分组,然后计算每个不同组中文档的数量。

db.coll.aggregate([ { $sortByCount: "$mainsubject.code" } ]


1

您需要按照聚合管道的$group阶段产生的字段名_id进行排序。因此,请按以下方式修改您的查询:

db.coll.aggregate([
  {
     $group: { 
        _id: "$mainsubject.code", 
        countA: { $sum: 1}
     }
  },
  {
     $sort:{_id:1}
  }
])

以这种方式排序,您正在按_id升序排列。您的SQL等效查询实际上是按count排序的,要实现这一点,可以将$sort阶段更改为:
$sort:{"countA":1}

你的答案也是正确的,但我选择了Ankit的答案,因为他的答案稍微短一些。 - bernhardh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接