$group(聚合)

在本页面

  • 定义

  • 注意事项

  • 例子

定义

  • $group

    • 按一些指定的表达式对文档进行分组,并为每个不同的分组输出到下一个阶段的文档。输出文档包含_id字段,其中包含 key by key。输出文档还可以包含计算字段,这些字段包含按$group的_id字段分组的某些累加器表达式的值。 $group不对其输出文档进行排序。

$group阶段具有以下原型形式:

{ $group: { _id: <expression>, <field1>: { <accumulator1> : <expression1> }, ... } }

_id字段是强制性的;但是,您可以指定_idvalue 为 null 或任何其他常量 value,以计算所有输入文档的累计值。

其余的计算字段是可选的,并使用<accumulator> operators 计算。

_id<accumulator>表达式可以接受任何有效的表达。有关表达式的更多信息,请参阅表达式。

注意事项

蓄能器操作员

<accumulator> operator 必须是以下累加器 operators 之一:

名称描述
$addToSet返回每个 group 的唯一表达式值的 array。 _Oray 元素的 Order 是未定义的。
$avg返回数值的平均值。忽略 non-numeric 值。
$first从每个 group 的第一个文档返回一个 value。仅当文档位于已定义的 order 中时才定义 Order。
$last从每个 group 的最后一个文档返回一个 value。仅当文档位于已定义的 order 中时才定义 Order。
$max返回每个 group 的最高表达式 value。
$mergeObjects返回通过组合每个 group 的输入文档创建的文档。
$min返回每个 group 的最低表达式 value。
$push返回每个 group 的表达式值的 array。
$stdDevPop返回输入值的总体标准偏差。
$stdDevSamp返回输入值的 sample 标准偏差。
$sum返回数值的总和。忽略 non-numeric 值。

$group Operator 和 Memory

$group阶段的 RAM 限制为 100 兆字节。默认情况下,如果阶段超出此限制,$group将产生错误。但是,要允许处理大型数据集,请将allowDiskUse选项设置为true以启用$group操作以写入临时 files。有关详细信息,请参见db.collection.aggregate()方法和骨料命令。

更改 version 2.6:MongoDB 为$group阶段引入了 100 兆字节的 RAM 限制,并为处理大型数据集的操作引入了allowDiskUse选项。

例子

计算计数,总和和平均值

给定一个带有以下文档的集合sales

{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-03-01T08:00:00Z") }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-03-01T09:00:00Z") }
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-03-15T09:00:00Z") }
{ "_id" : 4, "item" : "xyz", "price" : 5, "quantity" : 20, "date" : ISODate("2014-04-04T11:21:39.736Z") }
{ "_id" : 5, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-04-04T21:23:13.331Z") }

按月,日和年分组

以下聚合操作使用$group阶段按月,日和年对文档进行分组,并计算总价格和平均数量,并计算每个 group 的文档:

db.sales.aggregate(
   [
      {
        $group : {
           _id : { month: { $month: "$date" }, day: { $dayOfMonth: "$date" }, year: { $year: "$date" } },
           totalPrice: { $sum: { $multiply: [ "$price", "$quantity" ] } },
           averageQuantity: { $avg: "$quantity" },
           count: { $sum: 1 }
        }
      }
   ]
)

该操作返回以下结果:

{ "_id" : { "month" : 3, "day" : 15, "year" : 2014 }, "totalPrice" : 50, "averageQuantity" : 10, "count" : 1 }
{ "_id" : { "month" : 4, "day" : 4, "year" : 2014 }, "totalPrice" : 200, "averageQuantity" : 15, "count" : 2 }
{ "_id" : { "month" : 3, "day" : 1, "year" : 2014 }, "totalPrice" : 40, "averageQuantity" : 1.5, "count" : 2 }

Group by null

以下聚合操作指定null,计算总价格和平均数量以及集合中所有文档的计数:

db.sales.aggregate(
   [
      {
        $group : {
           _id : null,
           totalPrice: { $sum: { $multiply: [ "$price", "$quantity" ] } },
           averageQuantity: { $avg: "$quantity" },
           count: { $sum: 1 }
        }
      }
   ]
)

该操作返回以下结果:

{ "_id" : null, "totalPrice" : 290, "averageQuantity" : 8.6, "count" : 5 }

检索不同的值

给定一个带有以下文档的集合sales

{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-03-01T08:00:00Z") }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-03-01T09:00:00Z") }
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-03-15T09:00:00Z") }
{ "_id" : 4, "item" : "xyz", "price" : 5, "quantity" : 20, "date" : ISODate("2014-04-04T11:21:39.736Z") }
{ "_id" : 5, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-04-04T21:23:13.331Z") }

以下聚合操作使用$group阶段 item 对文档进行 group 以检索不同的 item 值:

db.sales.aggregate( [ { $group : { _id : "$item" } } ] )

该操作返回以下结果:

{ "_id" : "xyz" }
{ "_id" : "jkl" }
{ "_id" : "abc" }

枢轴数据

集合books包含以下文档:

{ "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 }
{ "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 }
{ "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 }
{ "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 }
{ "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 }

作者的组标题

以下聚合操作将books集合中的数据转向以使作者按标题分组。

db.books.aggregate(
   [
     { $group : { _id : "$author", books: { $push: "$title" } } }
   ]
)

该操作返回以下文档:

{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }
{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }

按作者分组文档

以下聚合操作使用$$ROOT系统变量按作者对文档进行 group。生成的文档不得超过BSON 文件大小限制。

db.books.aggregate(
   [
     { $group : { _id : "$author", books: { $push: "$$ROOT" } } }
   ]
)

该操作返回以下文档:

{
  "_id" : "Homer",
  "books" :
     [
       { "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 },
       { "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 }
     ]
}

{
  "_id" : "Dante",
  "books" :
     [
       { "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 },
       { "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 },
       { "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 }
     ]
}

也可以看看
使用 Zip Code 数据集进行聚合教程在 common 用例中提供了$group operator 的广泛示例。