MongoDB(34)什么是聚合管道(Aggregation Pipeline)?

9 阅读3分钟

聚合管道(Aggregation Pipeline)是MongoDB中一种强大的数据处理框架,用于对文档集合执行复杂的数据处理和转换操作。聚合管道通过将一系列的数据处理阶段(stages)连接在一起,类似于Unix管道,将数据从一个阶段传递到下一个阶段。每个阶段可以对数据进行过滤、排序、分组、转换等操作。

聚合管道的特点

  1. 多阶段处理:通过多个阶段依次处理数据,每个阶段执行特定的操作。
  2. 灵活性和强大性:支持丰富的操作符和表达式,能够实现复杂的数据处理逻辑。
  3. 性能优化:聚合管道在执行过程中会利用索引和内存优化,提供高效的数据处理能力。

聚合管道的基本语法

聚合管道使用 aggregate 方法,语法如下:

db.collection.aggregate([
    { $stage1: { /* stage1 options */ } },
    { $stage2: { /* stage2 options */ } },
    // Additional stages
])

常用的聚合阶段

  • $match:过滤文档,条件类似于 find 查询。
  • $group:将文档分组,并可进行计算(如求和、平均值、计数等)。
  • $sort:对文档进行排序。
  • $project:重新定义文档结构,可用于选择、计算和重命名字段。
  • $limit:限制返回的文档数量。
  • $skip:跳过指定数量的文档。
  • $unwind:将数组字段拆分成独立的文档。
  • $lookup:进行集合间的连接操作。

代码示例

以下是如何在不同编程语言和工具中使用聚合管道的详细示例。

使用MongoDB Shell进行聚合

  1. 插入示例数据
use myDatabase;

db.orders.drop(); // 删除现有的orders集合(如果存在)

db.orders.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" }
])
  1. 使用聚合管道
db.orders.aggregate([
    { $match: { status: "shipped" } }, // 过滤已发货的订单
    { $group: { _id: "$customerId", totalAmount: { $sum: "$amount" } } }, // 按customerId分组,并计算总金额
    { $sort: { totalAmount: -1 } } // 按总金额降序排序
])

这个聚合管道首先过滤出已发货的订单,然后按 customerId 分组,并计算每个客户的总订单金额,最后按总金额降序排序。

使用Node.js进行聚合

  1. 安装MongoDB Node.js驱动

在终端中运行以下命令来安装MongoDB的Node.js驱动:

npm install mongodb
  1. 创建并运行Node.js脚本

创建一个新的Node.js脚本文件(如 aggregation.js)并添加以下代码:

const { MongoClient } = require('mongodb');

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

    try {
        // 连接到MongoDB服务器
        await client.connect();
        console.log("Connected to MongoDB");

        // 选择数据库和集合
        const db = client.db('myDatabase');
        const collection = db.collection('orders');

        // 插入示例数据
        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" }
        ]);

        // 使用聚合管道
        const result = await collection.aggregate([
            { $match: { status: "shipped" } }, // 过滤已发货的订单
            { $group: { _id: "$customerId", totalAmount: { $sum: "$amount" } } }, // 按customerId分组,并计算总金额
            { $sort: { totalAmount: -1 } } // 按总金额降序排序
        ]).toArray();

        console.log("Aggregation result:", result);

    } finally {
        // 关闭连接
        await client.close();
    }
}

main().catch(console.error);

运行这个脚本:

node aggregation.js

使用Python进行聚合

  1. 安装PyMongo

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

pip install pymongo
  1. 创建并运行Python脚本

创建一个新的Python脚本文件(如 aggregation.py)并添加以下代码:

from pymongo import MongoClient

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

    # 插入示例数据
    collection.insert_many([
        { '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' }
    ])

    # 使用聚合管道
    pipeline = [
        { '$match': { 'status': 'shipped' } }, # 过滤已发货的订单
        { '$group': { '_id': '$customerId', 'totalAmount': { '$sum': '$amount' } } }, # 按customerId分组,并计算总金额
        { '$sort': { 'totalAmount': -1 } } # 按总金额降序排序
    ]

    result = list(collection.aggregate(pipeline))
    print("Aggregation result:", result)

    # 关闭连接
    client.close()

if __name__ == '__main__':
    main()

运行这个脚本:

python aggregation.py

总结

聚合管道是MongoDB中强大的数据处理工具,能够通过一系列的阶段对文档进行复杂的数据转换和分析操作。不同阶段提供了丰富的操作符和表达式,可以实现各种复杂的查询和数据处理任务。通过上述代码示例,你可以了解如何在MongoDB Shell、Node.js和Python中使用聚合管道对数据进行处理,这些示例展示了过滤、分组、排序等常见操作的基本用法。