13.MongoDB聚合管道

1.聚合管道作用

  • 使用聚合管道可以对集合中的文档进行变换和组合,在实际项目中可以做多表关联查询数据统计等工作

2.聚合管道常见操作符

管道操作符描述
$project增加、删除、重命名字段
$match条件匹配、只满足条件的文档才能进入下一阶段
$limit限制结果数量
$skip跳过文档的数量
$sort条件排序
$group条件组合、统计结果
$lookup$lookup操作符,用以引入其他集合的数据 (表关联)

3.管道操作符与SQL关键字对比

SQLNoSql
where$match
group by$group
having$match
select$project
order by$sort
limit$limit
sum()$sum
count()$sum
join$lookup

4.模拟数据

1.订单表
db.order.insert({"order_id":"1","uid":10,"trade_no":"111","all_price":100,"all_num":2})
db.order.insert({"order_id":"2","uid":7,"trade_no":"222","all_price":90,"all_num":2})
db.order.insert({"order_id":"3","uid":9,"trade_no":"333","all_price":20,"all_num":6})
2.订单商品表
db.order_item.insert({"order_id":"1","title":"商品鼠标 1","price":50,num:1})
db.order_item.insert({"order_id":"1","title":"商品键盘 2","price":50,num:1})
db.order_item.insert({"order_id":"1","title":"商品键盘 3","price":0,num:1})
db.order_item.insert({"order_id":"2","title":"牛奶","price":50,num:1})
db.order_item.insert({"order_id":"2","title":"酸奶","price":40,num:1})
db.order_item.insert({"order_id":"3","title":"矿泉水","price":2,num:5})
db.order_item.insert({"order_id":"3","title":"毛巾","price":10,num:1})

在这里插入图片描述

5.$project

1.作用
  • 修改文档结构,可以用来重命名、增加、删除文档中的字段
2.需求
  • 要求查找集合order中的数据,只返回文档中trade_noall_price字段
db.order.aggregate(
	[
		{
			$project: {trade_no: 1, all_price: 1}
		}
	]
)

// db.order.find({},{"trade_no": 1, "all_price": 1})

6.$match

1.作用:
  • 用于过滤文档,类似于find方法中的参数
2.需求
  • 要求查找集合order中的数据,只返回文档中trade_noall_price字段,且过滤掉all_price小于90的数据
db.order.aggregate(
	[
		{
			$project: {trade_no: 1, all_price: 1}
		},
		{
			$match: {"all_price": {$gte: 90}}
		}
	]
)

// db.order.find({"all_price": {$gte: 90}},{"trade_no": 1, "all_price": 1})

7.$group

1.作用
  • 将集合中的文档进行分组,可用于统计结果
2.需求
  • 统计每个订单下的商品总数量,按照订单号分组
db.order_item.aggregate(
	[
		{
			$group: {_id: "$order_id", total: {$sum: "$num"}}
		}
	]
)
// select count(num) from order_item group by order_id;

8.$sort

1.作用
  • 将集合中的文档进行排序
2.需求
  • 要求查找集合order中的数据,只返回文档中trade_noall_price字段,且过滤掉all_price小于90的数据,最后按照all_price进行降序排序
db.order.aggregate(
	[
		{
			$project: {trade_no: 1, all_price: 1}
		},
		{
			$match: {"all_price": {$gte: 90}}
		},
		{
			$sort: {"all_price": -1}
		}
	]
)

// db.order.find({"all_price": {$gte: 90}},{"trade_no": 1, "all_price": 1}).sort({"all_price": -1})
// select trade_no, all_price from order where all_price >= 90 order by all_price desc;

9.$limit

1.作用
  • 限制返回数据数量
2.需求
  • 要求查找集合order中的数据,只返回文档中trade_noall_price字段,且过滤掉all_price小于90的数据,最后按照all_price进行降序排序,返回第一条数据
db.order.aggregate(
	[
		{
			$project: {trade_no: 1, all_price: 1}
		},
		{
			$match: {"all_price": {$gte: 90}}
		},
		{
			$sort: {"all_price": -1}
		},
		{
			$limit: 1
		}
	]
)

// db.order.find({"all_price": {$gte: 90}},{"trade_no": 1, "all_price": 1}).sort({"all_price": -1}).limit(1);
// select trade_no, all_price from order where all_price >= 90 order by all_price desc limit 1;

10.$skip

1.作用
  • 跳过前n条数据
2.需求
  • 要求查找集合order中的数据,只返回文档中trade_noall_price字段,且过滤掉all_price小于90的数据,最后按照all_price进行降序排序,跳过第一条数据后返回第一条数据
db.order.aggregate(
	[
		{
			$project: {trade_no: 1, all_price: 1}
		},
		{
			$match: {"all_price": {$gte: 90}}
		},
		{
			$sort: {"all_price": -1}
		},
		{
			$skip: 1
		},
		{
			$limit: 1
		}
	]
)

// db.order.find({"all_price": {$gte: 90}},{"trade_no": 1, "all_price": 1}).sort({"all_price": -1}).skip(1).limit(1);
// select trade_no, all_price from order where all_price >= 90 order by all_price desc limit 1 offset 1;

11.lookup

1.作用
  • 表关联
2.需求
  • 返回订单信息,包含每条订单下的商品信息
db.order.aggregate([
	{
		$lookup: {
			from: "order_item",
			localField: "order_id",
			foreignField: "order_id",
			as: "items"
		}
	}
])
  • 订单信息只显示order_idall_price字段
db.order.aggregate([
	{
		$project: {order_id: 1, all_price: 1}
	},
	{
		$lookup: {
			from: "order_item",
			localField: "order_id",
			foreignField: "order_id",
			as: "items"
		}
	}
])
  • 订单信息只显示order_idall_price字段,订单内商品只显示titlepricenum

db.order.aggregate([
	{
		$lookup: {
			from: "order_item",
			localField: "order_id",
			foreignField: "order_id",
			as: "items"
		}
	},
	{
		$project: {
			order_id: 1, 
			all_price: 1,
			items: {
				title: 1,
				price: 1,
				num: 1
			}
		}
	}
])
  • 过滤出订单内商品价格大于等于10元的数据:$filter
db.order.aggregate([
	{
		$lookup: {
			from: "order_item",
			localField: "order_id",
			foreignField: "order_id",
			as: "items"
		}
	},
	{
		$project: {
			order_id: 1, 
			all_price: 1,
			items: {
				"$filter": {
					input: "$items",
					as: "shop",
					cond: { 
						$gte: [
							"$$shop.price", 
							10
						] 
					}
				}
			}	
		}
	}
])
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值