https://docs.mongodb.com/manual/reference/operator/aggregation/group/
语法示例:

  1. {
  2. $group:
  3. {
  4. _id: <expression>, // Group By Expression
  5. <field1>: { <accumulator1> : <expression1> },
  6. ...
  7. }
  8. }
  1. db.sales.insertMany([
  2. { "_id" : 1, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("2"), "date" : ISODate("2014-03-01T08:00:00Z") },
  3. { "_id" : 2, "item" : "jkl", "price" : NumberDecimal("20"), "quantity" : NumberInt("1"), "date" : ISODate("2014-03-01T09:00:00Z") },
  4. { "_id" : 3, "item" : "xyz", "price" : NumberDecimal("5"), "quantity" : NumberInt( "10"), "date" : ISODate("2014-03-15T09:00:00Z") },
  5. { "_id" : 4, "item" : "xyz", "price" : NumberDecimal("5"), "quantity" : NumberInt("20") , "date" : ISODate("2014-04-04T11:21:39.736Z") },
  6. { "_id" : 5, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("10") , "date" : ISODate("2014-04-04T21:23:13.331Z") },
  7. { "_id" : 6, "item" : "def", "price" : NumberDecimal("7.5"), "quantity": NumberInt("5" ) , "date" : ISODate("2015-06-04T05:08:13Z") },
  8. { "_id" : 7, "item" : "def", "price" : NumberDecimal("7.5"), "quantity": NumberInt("10") , "date" : ISODate("2015-09-10T08:43:00Z") },
  9. { "_id" : 8, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("5" ) , "date" : ISODate("2016-02-06T20:20:13Z") },
  10. ])

Count the Number of Documents in a Collection

  1. '''
  2. SELECT COUNT(*) AS count FROM sales
  3. '''
  4. db.sales.aggregate( [
  5. {
  6. $group: {
  7. _id: null,
  8. count: { $sum: 1 }
  9. }
  10. }
  11. ] )
  12. >>> { "_id" : null, "count" : 8 }

Retrieve Distinct Values

  1. db.sales.aggregate( [ { $group : { _id : "$item" } } ] )
  2. >>>{ "_id" : "abc" }
  3. { "_id" : "jkl" }
  4. { "_id" : "def" }
  5. { "_id" : "xyz" }

Group by Item Having

  1. '''
  2. SELECT item,
  3. Sum(( price * quantity )) AS totalSaleAmount
  4. FROM sales
  5. GROUP BY item
  6. HAVING totalSaleAmount >= 100
  7. '''
  8. db.sales.aggregate(
  9. [
  10. // First Stage
  11. {
  12. $group :
  13. {
  14. _id : "$item",
  15. totalSaleAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } }
  16. }
  17. },
  18. // Second Stage
  19. {
  20. $match: { "totalSaleAmount": { $gte: 100 } }
  21. }
  22. ]
  23. )
  24. >>>{ "_id" : "abc", "totalSaleAmount" : NumberDecimal("170") }
  25. { "_id" : "xyz", "totalSaleAmount" : NumberDecimal("150") }
  26. { "_id" : "def", "totalSaleAmount" : NumberDecimal("112.5") }

Group by Day of the Year

  1. '''
  2. SELECT date,
  3. Sum(( price * quantity )) AS totalSaleAmount,
  4. Avg(quantity) AS averageQuantity,
  5. Count(*) AS Count
  6. FROM sales
  7. GROUP BY Date(date)
  8. ORDER BY totalSaleAmount DESC
  9. '''
  10. db.sales.aggregate([
  11. // First Stage
  12. {
  13. $match : { "date": { $gte: new ISODate("2014-01-01"), $lt: new ISODate("2015-01-01") } }
  14. },
  15. // Second Stage
  16. {
  17. $group : {
  18. _id : { $dateToString: { format: "%Y-%m-%d", date: "$date" } },
  19. totalSaleAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } },
  20. averageQuantity: { $avg: "$quantity" },
  21. count: { $sum: 1 }
  22. }
  23. },
  24. // Third Stage
  25. {
  26. $sort : { totalSaleAmount: -1 }
  27. }
  28. ])
  29. >>>{ "_id" : "2014-04-04", "totalSaleAmount" : NumberDecimal("200"), "averageQuantity" : 15, "count" : 2 }
  30. { "_id" : "2014-03-15", "totalSaleAmount" : NumberDecimal("50"), "averageQuantity" : 10, "count" : 1 }
  31. { "_id" : "2014-03-01", "totalSaleAmount" : NumberDecimal("40"), "averageQuantity" : 1.5, "count" : 2 }

Group by null

The following aggregation operation specifies a group _id of null, calculating the total sale amount, average quantity, and count of all documents in the collection.

  1. '''
  2. SELECT Sum(price * quantity) AS totalSaleAmount,
  3. Avg(quantity) AS averageQuantity,
  4. Count(*) AS Count
  5. FROM sales
  6. '''
  7. db.sales.aggregate([
  8. {
  9. $group : {
  10. _id : null,
  11. totalSaleAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } },
  12. averageQuantity: { $avg: "$quantity" },
  13. count: { $sum: 1 }
  14. }
  15. }
  16. ])
  17. >>>{
  18. "_id" : null,
  19. "totalSaleAmount" : NumberDecimal("452.5"),
  20. "averageQuantity" : 7.875,
  21. "count" : 8
  22. }

Pivot Data

From the mongo shell, create a sample collection named books with the following documents:

  1. db.books.insertMany([
  2. { "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 },
  3. { "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 },
  4. { "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 },
  5. { "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 },
  6. { "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 }
  7. ])

Group title by author

  1. db.books.aggregate([
  2. { $group : { _id : "$author", books: { $push: "$title" } } }
  3. ])
  4. >>>{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }
  5. { "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }

Group Documents by author

The following aggregation operation groups documents by author:

  1. db.books.aggregate([
  2. // First Stage
  3. {
  4. $group : { _id : "$author", books: { $push: "$$ROOT" } }
  5. },
  6. // Second Stage
  7. {
  8. $addFields:
  9. {
  10. totalCopies : { $sum: "$books.copies" }
  11. }
  12. }
  13. ])
  1. >>> {
  2. "_id" : "Homer",
  3. "books" :
  4. [
  5. { "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 },
  6. { "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 }
  7. ],
  8. "totalCopies" : 20
  9. }
  10. {
  11. "_id" : "Dante",
  12. "books" :
  13. [
  14. { "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 },
  15. { "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 },
  16. { "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 }
  17. ],
  18. "totalCopies" : 5
  19. }