MongoDB 聚合查询详解
MongoDB 是一个面向文档的 NoSQL 数据库,提供了丰富的聚合查询操作。聚合查询可以帮助我们分析和处理数据,如求和、求平均值、分组等操作。本文将详细介绍 MongoDB 聚合查询的语法和使用方法,并提供了两个实例进行说明。
MongoDB 聚合查询语法
聚合查询使用聚合管道(pipe)的方式对文档进行操作。聚合管道由一系列各种聚合阶段(stage)组成。每个聚合阶段包含一个操作符(operator)和其相应的参数。聚合阶段按照定义的顺序依次执行,并将输出作为下一阶段的输入。下面是 MongoDB 聚合查询的语法模板:
db.collection.aggregate([
{ $match: { /* 查询条件 */ } },
{ $project: { /* 投影字段 */ } },
{ $group: { /* 分组字段 */ } },
{ $sort: { /* 排序字段 */ } },
{ $limit: /* 限制数量 */ },
{ $skip: /* 跳过数量 */ },
{ $unwind: { /* 展开嵌套字段 */ } },
// ...
]);
上述语法模板中,各聚合阶段的作用如下:
$match
阶段:用于筛选符合条件的文档,相当于find
方法的查询条件。$project
阶段:用于选择需要输出的字段,相当于 SQL 中的SELECT
语句。$group
阶段:用于按照指定字段分组,并进行聚合操作,如求和、计数、取最大值等。$sort
阶段:用于排序,可以按照指定字段升降序排列。$limit
阶段:用于限制输出的文档数量。$skip
阶段:用于跳过指定数量的文档。$unwind
阶段:用于展开嵌套的数组字段。
除上述聚合阶段外,MongoDB 还提供了丰富的聚合操作符,用于实现各种聚合操作。
MongoDB 聚合查询示例
示例 1:统计成绩
假设我们有一个学生成绩的集合,包含如下的文档:
db.scores.insertMany([
{ name: '张三', subject: '语文', score: 80 },
{ name: '张三', subject: '数学', score: 90 },
{ name: '李四', subject: '语文', score: 85 },
{ name: '李四', subject: '数学', score: 95 },
{ name: '王五', subject: '语文', score: 90 },
{ name: '王五', subject: '数学', score: 80 },
]);
我们需要统计每个学生各科目的总分和平均分,并按照总分从高到低排序。可以使用如下的聚合查询:
db.scores.aggregate([
{ $group: { _id: { name: '$name', subject: '$subject' }, total: { $sum: '$score' } } },
{ $group: { _id: '$_id.name', subjects: { $push: { name: '$_id.subject', total: '$total' } }, total: { $sum: '$total' }, avg: { $avg: '$total' } } },
{ $sort: { total: -1 } },
{ $project: { _id: 0, name: '$_id', total: 1, avg: 1, subjects: { $arrayToObject: { $map: { input: '$subjects', as: 's', in: { k: '$$s.name', v: '$$s.total' } } } } } },
]);
上述聚合查询的含义如下:
- 第一阶段使用
$group
操作符按照name
和subject
分组,统计每个学生每门课程的总分。 - 第二阶段使用
$group
操作符按照name
分组,将每个学生各科目的总分整合到一个数组中,并统计每个学生的总分和平均分。 - 第三阶段使用
$sort
操作符按照total
从高到低排序。 - 第四阶段使用
$project
操作符选择输出的字段,并使用$arrayToObject
操作符将科目成绩的数组转换为对象格式。
执行上述聚合查询后,输出结果如下:
[
{
"name": "李四",
"total": 180,
"avg": 90,
"subjects": {
"语文": 85,
"数学": 95
}
},
{
"name": "张三",
"total": 170,
"avg": 85,
"subjects": {
"语文": 80,
"数学": 90
}
},
{
"name": "王五",
"total": 170,
"avg": 85,
"subjects": {
"语文": 90,
"数学": 80
}
}
]
示例 2:多表聚合
假设我们有一个用户和订单的数据,其中用户信息储存在 users
集合中,订单信息储存在 orders
集合中,并使用 userid
字段关联两个集合。我们需要统计每个用户的订单数量、总金额以及平均金额。可以使用如下的聚合查询:
db.users.aggregate([
{ $lookup: { from: 'orders', localField: '_id', foreignField: 'userid', as: 'orders' } },
{ $unwind: '$orders' },
{ $group: { _id: '$_id', total: { $sum: '$orders.amount' }, count: { $sum: 1 } } },
{ $project: { _id: 0, name: '$username', total: 1, count: 1, avg: { $divide: ['$total', '$count'] } } },
]);
上述聚合查询的含义如下:
- 第一阶段使用
$lookup
操作符关联orders
集合,并将结果保存到orders
字段中。 - 第二阶段使用
$unwind
操作符展开orders
数组。 - 第三阶段使用
$group
操作符按照userid
统计每个用户的订单总金额和数量。 - 第四阶段使用
$project
操作符选择输出的字段,并使用$divide
操作符计算平均金额。
执行上述聚合查询后,输出结果如下:
[
{ "name" : "张三", "total" : 80, "count" : 1, "avg" : 80 },
{ "name" : "李四", "total" : 200, "count" : 2, "avg" : 100 },
{ "name" : "王五", "total" : 60, "count" : 1, "avg" : 60 },
]
以上就是 MongoDB 聚合查询的详细介绍和两个实例的说明。聚合查询是 MongoDB 强大的功能之一,掌握了聚合查询,我们可以更加高效地进行数据处理和分析。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:MongoDB 聚合查询详解 - Python技术站