# 聚合例子

# 数据集

假设有一个名为 books 的图书集合,其示例数据结构如下:

{
  "_id": "xxxx-xxxx-xxxx",
  "category": "novel",
  "title": "title 1",
  "author": "author 1",
  "sales": 5000,
  "monthlySales": [1000, 1500, 2500]
}

# 例:求各类图书的平均销量

采用 books 图书数据集作为示例。求各类图书的平均销量的操作等价于将图书按类别(category)分组,然后对每组的销量(sales)求平均值,最后返回类别和平均销量信息。

const db = wx.cloud.database()
const $ = db.command.aggregate
const result = await db.collection('books').aggregate()
  .group({
    // 按 category 字段分组
    _id: '$category',
    // 每组有一个 avgSales 字段,其值是组内所有记录的 sales 字段的平均值
    avgSales: $.avg('$sales')
  })
  .end()

返回结果示例如下:

{
  "list": [
    {
      _id: "novel", // 组名
      sales: 1035, // 组平均销量
    },
    {
      _id: "science", // 组名
      sales: 350, // 组平均销量
    }
  ]
}

用到的聚合流水线阶段:group

用到的聚合流水线操作符:avg

# 例:求各类图书的最高销量作者和最低销量作者及其销量

采用 books 图书数据集作为示例。一个作者在一个图书类目下可能有多本书,这个操作可以分阶段进行批处理:

  • 第一阶段: 按 "图书类目 + 作者" 进行分组,求得每个作者在该图书类目下的多本书的总销量
  • 第二阶段: 将上一个阶段得到的结果按总销量排倒序,求得各图书类目作者的总销量排序
  • 第三阶段: 将上一个阶段得到的结果按类目分组,各组分别取组中第一项(销量最高)和最后一项(销量最低)的作者名和总销量,返回最终结果
const db = wx.cloud.database()
const $ = db.command.aggregate
const result = db.collection('books').aggregate()
  .group({
    _id: {
      category: '$category',
      author: '$author',
    },
    totalSales: $.sum('$sales')
  })
  .sort({
    totalSales: -1,
  })
  .group({
    _id: '$_id.category',
    bestSellingAuthor: $.first('$_id.author'),
    bestSellingAuthorTotalSales: $.first('$totalSales'),
    worstSellingAuthor: $.last('$_id.author'),
    worstSellingAuthorTotalSales: $.last('$totalSales'),
  })
  .end().then(console.log)

返回结果示例如下:

{
  "list": [
    {
      "_id": "novel",
      "bestSellingAuthor": "author 1",
      "bestSellingAuthorTotalSales": 550,
      "worstSellingAuthor": "author 2",
      "worstSellingAuthorTotalSales": 1520
    },
    {
      "_id": "science",
      "bestSellingAuthor": "author 4",
      "bestSellingAuthorTotalSales": 1050,
      "worstSellingAuthor": "author 3",
      "worstSellingAuthorTotalSales": 3000
    }
  ]
}

用到的聚合流水线阶段:groupsort

用到的聚合流水线操作符:sumfirstlast