在MongoDB中,使用聚合管道进行分组操作的关键阶段是 $group。该阶段允许你根据一个或多个字段将文档分组,并可以在每个组上进行各种计算,比如求和、求平均值、计数等。
使用 $group 阶段进行分组
$group 阶段的基本结构如下:
{
$group: {
_id: <group key>, // 分组字段
<field1>: { <accumulator1>: <expression1> },
<field2>: { <accumulator2>: <expression2> },
// 其他字段和计算
}
}
常见的累加器(accumulators)包括:
$sum:计算总和$avg:计算平均值$min:计算最小值$max:计算最大值$push:将值添加到数组$addToSet:将唯一值添加到数组$first:获取第一个值$last:获取最后一个值
代码示例
以下是使用Node.js进行分组操作的详细示例。首先确保安装了MongoDB的Node.js驱动:
npm install mongodb
插入示例数据
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);
使用聚合管道进行分组
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 阶段进行分组操作:
- 分组键:
$customerId,即我们按customerId字段分组。 - 计算总金额:
totalAmount,使用$sum计算每个客户的总订单金额。 - 计算平均订单金额:
avgAmount,使用$avg计算每个客户的平均订单金额。 - 计算订单数量:
orderCount,使用$sum并传入值1计算每个客户的订单数量。 - 收集订单:
orders,使用$push将每个客户的所有订单放入一个数组。
运行这个脚本后,你会得到如下结果(示例输出):
[
{
"_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:
pip install pymongo
使用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的聚合管道进行分组操作,并在每个组上执行各种计算。