MongoDB(36)如何使用聚合进行分组?

在MongoDB中,使用聚合管道进行分组操作的关键阶段是 $group。该阶段允许你根据一个或多个字段将文档分组,并可以在每个组上进行各种计算,比如求和、求平均值、计数等。

使用 $group 阶段进行分组

$group 阶段的基本结构如下:

javascript 复制代码
{ 
  $group: {
    _id: <group key>, // 分组字段
    <field1>: { <accumulator1>: <expression1> },
    <field2>: { <accumulator2>: <expression2> },
    // 其他字段和计算
  } 
}

常见的累加器(accumulators)包括:

  • $sum:计算总和
  • $avg:计算平均值
  • $min:计算最小值
  • $max:计算最大值
  • $push:将值添加到数组
  • $addToSet:将唯一值添加到数组
  • $first:获取第一个值
  • $last:获取最后一个值

代码示例

以下是使用Node.js进行分组操作的详细示例。首先确保安装了MongoDB的Node.js驱动:

bash 复制代码
npm install mongodb
插入示例数据
javascript 复制代码
const { MongoClient } = require('mongodb');

async function insertData() {
    const uri = "mongodb://localhost:27017";
    const client = new MongoClient(uri, { useUnifiedTopology: true });

    try {
        await client.connect();
        const db = client.db('myDatabase');
        const collection = db.collection('orders');

        await collection.deleteMany({}); // 清空集合

        await collection.insertMany([
            { customerId: 1, amount: 100, status: "shipped" },
            { customerId: 1, amount: 200, status: "pending" },
            { customerId: 2, amount: 150, status: "shipped" },
            { customerId: 2, amount: 50, status: "pending" },
            { customerId: 3, amount: 250, status: "shipped" }
        ]);

        console.log("Data inserted");
    } finally {
        await client.close();
    }
}

insertData().catch(console.error);
使用聚合管道进行分组
javascript 复制代码
async function aggregateData() {
    const uri = "mongodb://localhost:27017";
    const client = new MongoClient(uri, { useUnifiedTopology: true });

    try {
        await client.connect();
        const db = client.db('myDatabase');
        const collection = db.collection('orders');

        // 使用 $group 进行分组
        console.log("\n$group stage:");
        let result = await collection.aggregate([
            { $group: { 
                _id: "$customerId", 
                totalAmount: { $sum: "$amount" }, // 计算每个客户的总金额
                avgAmount: { $avg: "$amount" },   // 计算每个客户的平均订单金额
                orderCount: { $sum: 1 },          // 计算每个客户的订单数量
                orders: { $push: "$$ROOT" }       // 将每个客户的订单放入数组
            }}
        ]).toArray();
        console.log(result);

    } finally {
        await client.close();
    }
}

aggregateData().catch(console.error);

在这个示例中,我们演示了如何使用 $group 阶段进行分组操作:

  1. 分组键$customerId,即我们按 customerId 字段分组。
  2. 计算总金额totalAmount,使用 $sum 计算每个客户的总订单金额。
  3. 计算平均订单金额avgAmount,使用 $avg 计算每个客户的平均订单金额。
  4. 计算订单数量orderCount,使用 $sum 并传入值 1 计算每个客户的订单数量。
  5. 收集订单orders,使用 $push 将每个客户的所有订单放入一个数组。

运行这个脚本后,你会得到如下结果(示例输出):

javascript 复制代码
[
  {
    "_id": 1,
    "totalAmount": 300,
    "avgAmount": 150,
    "orderCount": 2,
    "orders": [
      { "customerId": 1, "amount": 100, "status": "shipped" },
      { "customerId": 1, "amount": 200, "status": "pending" }
    ]
  },
  {
    "_id": 2,
    "totalAmount": 200,
    "avgAmount": 100,
    "orderCount": 2,
    "orders": [
      { "customerId": 2, "amount": 150, "status": "shipped" },
      { "customerId": 2, "amount": 50, "status": "pending" }
    ]
  },
  {
    "_id": 3,
    "totalAmount": 250,
    "avgAmount": 250,
    "orderCount": 1,
    "orders": [
      { "customerId": 3, "amount": 250, "status": "shipped" }
    ]
  }
]

其他语言示例

类似的分组操作也可以在其他编程语言中实现,如Python。以下是Python的示例代码:

安装PyMongo

在终端中运行以下命令来安装PyMongo:

bash 复制代码
pip install pymongo
使用Python进行分组
python 复制代码
from pymongo import MongoClient

def main():
    client = MongoClient('mongodb://localhost:27017/')
    db = client['myDatabase']
    collection = db['orders']

    # 使用 $group 进行分组
    pipeline = [
        { '$group': { 
            '_id': '$customerId', 
            'totalAmount': { '$sum': '$amount' }, 
            'avgAmount': { '$avg': '$amount' }, 
            'orderCount': { '$sum': 1 }, 
            'orders': { '$push': '$$ROOT' } 
        }}
    ]

    result = list(collection.aggregate(pipeline))
    print(result)

if __name__ == '__main__':
    main()

运行这个脚本后,你会得到类似的结果。通过这些示例,你可以了解到如何在不同编程语言中使用MongoDB的聚合管道进行分组操作,并在每个组上执行各种计算。

相关推荐
oradh9 小时前
Oracle闪回技术操作总结
数据库·oracle·oracle闪回技术操作总结·oracle闪回·flashback技术
ltl9 小时前
RocksDB 并发 Compaction 与 Rate Limiter
数据库
闻道且行之11 小时前
图片处理助手|泊松融合原理 + C++ 工程实现,seamlessClone 三模式一次讲透
数据库·c++·人工智能·opencv
夏炳辉.12 小时前
PostgreSQL 高可用集群核心配置参数全解:从原生流复制到 Patroni 企业级方案
数据库·postgresql
努力的小雨13 小时前
KES 开启 SSL 前,证书、端口和客户端要一起验
数据库
DevOps老兵13 小时前
AI全栈知识07:向量数据库 - Milvus/Chroma实战
数据库·ai·milvus
这个DBA有点耶13 小时前
当数据库从“存储”走向“决策”:金仓数据库的融合架构之路
数据库·架构·aigc
smilejingwei13 小时前
Trae+SQLazy 实践 SQL 国产化移植:Oracle => 达梦
数据库·sql·oracle
意疏14 小时前
2026年远控软件安全横评:六款主流工具逐项核查——官方文档、一手实测与安全事件,全摊开
大数据·前端·数据库
名不经传的养虾人14 小时前
从0到1:企业级AI项目迭代日记 Vol.90|Agent变快了,Judge定下来了
大数据·数据库·人工智能·ai编程·企业ai