系列十三、MongoDB聚合查询

一、概述

        MongoDB聚合框架(Aggregation Framework)是一个计算框架,为集合文档数据提供各种处理数据的方法,并返回计算结果。MongoDB提供了三种方式来执行聚合(Aggregation)命令,即:聚合管道方法、map-reduce方法、单一目标聚合方法。常见功能:

①:作用在一个或者几个集合上;

②:对集合中的数据进行一系列的运算;

③:将这些数据转化为期望的形式;

从效果而言,聚合框架相当于SQL中的 group by、left outer join、as等。

1.1、聚合管道方法

管道在Unix或者Linux中一般用于将当前指令的输出结果作为下一个命令的参数。MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。

二、聚合

2.1、管道(Pipeline)和步骤(Stage)

整个聚合运算过程称为管道(Pipeline),它是由多个步骤(Stage)组成的,每个管道:

①:接受一系列文档(原始数据);

②:每个步骤对这些文档进行一系列运算;

③:结果文档输出给下一个步骤;

2.2、基本格式

pipline = [$stage1,$stage2,...$stageN]

db..aggregate(
    pipline,
    { options }
);

2.3、常见步骤

系列十三、MongoDB聚合查询_第1张图片

 2.3.1、常见步骤中的运算符

系列十三、MongoDB聚合查询_第2张图片

 2.4、少见步骤

系列十三、MongoDB聚合查询_第3张图片

2.5、使用场景

聚合查询可以用于OLAP和OLTP场景,例如:

系列十三、MongoDB聚合查询_第4张图片

 2.6、MQL常用步骤与SQL对比

2.6.1、vs1

系列十三、MongoDB聚合查询_第5张图片

 2.6.2、vs2

系列十三、MongoDB聚合查询_第6张图片

 2.6.3、特有步骤$unwind

系列十三、MongoDB聚合查询_第7张图片

 2.6.4、特有步骤$bucket

系列十三、MongoDB聚合查询_第8张图片

 2.6.5、特有步骤$facet

系列十三、MongoDB聚合查询_第9张图片

三、实验一

3.1、初始化数据

db.orders.insert(
	[
		{
			"street": "西兴街道",
			"city": "杭州",
			"state": "浙江省",
			"country": "中国",
			"zip": "24344-1715",
			"phone": "18866668888",
			"name": "李白",
			"userId": "3573",
			"orderDate": "2019-01-02 03:20:08.805",
			"status": "completed",
			"shippingFee": 8.00,
			"orderLines": [{
					"product": "iPhone5",
					"sku": "2001",
					"qty": 1,
					"price": 100.00,
					"cost": 100.00
				},
				{
					"product": "iPhone5s",
					"sku": "2002",
					"qty": 2,
					"price": 200.00,
					"cost": 400.00
				},
				{
					"product": "iPhone6",
					"sku": "2003",
					"qty": 1,
					"price": 300.00,
					"cost": 300.00
				},
				{
					"product": "iPhone6s",
					"sku": "2004",
					"qty": 2,
					"price": 400.00,
					"cost": 800.00
				},
				{
					"product": "iPhone8",
					"sku": "2005",
					"qty": 2,
					"price": 500.00,
					"cost": 1000.00
				}
			],
			"total": 2600
		},
		{
			"street": "长河街道",
			"city": "杭州",
			"state": "浙江省",
			"country": "中国",
			"zip": "24344-1716",
			"phone": "18866668881",
			"name": "杜甫",
			"userId": "3574",
			"orderDate": "2019-02-02 13:20:08.805",
			"status": "completed",
			"shippingFee": 5.00,
			"orderLines": [{
					"product": "iPhone5",
					"sku": "2001",
					"qty": 1,
					"price": 100.00,
					"cost": 100.00
				},
				{
					"product": "iPhone5s",
					"sku": "2002",
					"qty": 2,
					"price": 200.00,
					"cost": 400.00
				},
				{
					"product": "iPhone6",
					"sku": "2003",
					"qty": 1,
					"price": 300.00,
					"cost": 300.00
				},
				{
					"product": "iPhone6s",
					"sku": "2004",
					"qty": 2,
					"price": 400.00,
					"cost": 800.00
				},
				{
					"product": "iPhone8",
					"sku": "2005",
					"qty": 2,
					"price": 500.00,
					"cost": 1000.00
				}
			],
			"total": 2600
		},
		{
			"street": "浦沿街道",
			"city": "杭州",
			"state": "浙江省",
			"country": "中国",
			"zip": "24344-1717",
			"phone": "18866668882",
			"name": "王安石",
			"userId": "3575",
			"orderDate": "2019-03-02 14:20:08.805",
			"status": "completed",
			"shippingFee": 20.00,
			"orderLines": [{
					"product": "iPhone5",
					"sku": "2001",
					"qty": 1,
					"price": 100.00,
					"cost": 100.00
				},
				{
					"product": "iPhone5s",
					"sku": "2002",
					"qty": 2,
					"price": 200.00,
					"cost": 400.00
				},
				{
					"product": "iPhone6",
					"sku": "2003",
					"qty": 1,
					"price": 300.00,
					"cost": 300.00
				},
				{
					"product": "iPhone6s",
					"sku": "2004",
					"qty": 2,
					"price": 400.00,
					"cost": 800.00
				},
				{
					"product": "iPhone12 ProMax",
					"sku": "2006",
					"qty": 1,
					"price": 1500.00,
					"cost": 1500.00
				}
			],
			"total": 3100
		},
		{
			"street": "长庆街道",
			"city": "杭州",
			"state": "浙江省",
			"country": "中国",
			"zip": "24344-1717",
			"phone": "18866668883",
			"name": "苏东坡",
			"userId": "3576",
			"orderDate": "2019-04-02 15:20:08.805",
			"status": "completed",
			"shippingFee": 10.00,
			"orderLines": [
				{
					"product": "iPhone6s",
					"sku": "2004",
					"qty": 2,
					"price": 400.00,
					"cost": 800.00
				},
				{
					"product": "iPhone12 ProMax",
					"sku": "2006",
					"qty": 1,
					"price": 1500.00,
					"cost": 1500.00
				}
			],
			"total": 2300
		}
	]
)

 3.2、案例一:计算到目前为止的所有订单的总销售额

db.orders.aggregate(
	[
		{
			$group:{
				_id: null,
				total: {$sum:"$total"}
			}
		}
	]
)

 系列十三、MongoDB聚合查询_第10张图片

 3.3、案例二:查询2019年第一季度(1月1日-3月31日)已完成订单(completed)的订单总金额和订单总数

db.orders.aggregate(
	[
	  {
		'$match': {
		  'status': 'completed', 
		  'orderDate': {
			'$gte': '2019-01-01', 
			'$lt': '2019-04-01'
		  }
		}
	  }, {
		'$group': {
		  '_id': null, 
		  'total': {
			'$sum': '$total'
		  }, 
		  'shippingFee': {
			'$sum': '$shippingFee'
		  }, 
		  'count': {
			'$sum': 1
		  }
		}
	  }, {
		'$project': {
		  'grandTotal': {
			'$add': [
			  '$total', '$shippingFee'
			]
		  }, 
		  '_id': 0
		}
	  }
	]
)

系列十三、MongoDB聚合查询_第11张图片

四、实验二

案例一、$project实例

db.article.aggregate({
	$project: {
		title: 1,
		author: 1
	}
})
说明:执行结果中将包含_id、title、author三个字段,默认情况下_id字段是被包含的。1:显示、0:不显示

案例二、$match实例

db.article.aggregate([
	{
		$match: {
			score: {$gt: 70,$lte: 90}
		}
	},
	{
		$group: {
			_id: null,count: {$sum:1}
		}
	}
])
说明:$match用于获取分数大于70小于等于90的记录,然后将符合条件的记录送到下一阶段$group管道操作符进行处理

你可能感兴趣的:(mongodb,数据库)