• 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})
    
    • 1
    • 2
    • 3
    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})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    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})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    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})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    11.lookup

    1.作用
    • 表关联
    2.需求
    • 返回订单信息,包含每条订单下的商品信息
    db.order.aggregate([
    	{
    		$lookup: {
    			from: "order_item",
    			localField: "order_id",
    			foreignField: "order_id",
    			as: "items"
    		}
    	}
    ])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 订单信息只显示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"
    		}
    	}
    ])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 订单信息只显示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
    			}
    		}
    	}
    ])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 过滤出订单内商品价格大于等于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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
  • 相关阅读:
    【饭谈】在学习测开网课之前,你的心脏需要武装一下
    07-Redis【Redis主从复制,终于有人讲明白了】
    02-分布式协调服务ZooKeeper
    小白学Java
    使用xlwings获取excel表的行和列以及指定单元格的值
    【编程题】【Scratch四级】2021.12 聪明的小猫
    概率的学习和整理--番外6:概率的学习方法 和 解题方法
    网络安全学习:系统文本编辑命令
    自建音乐服务器Navidrome之一
    在关系数据库中允许空值的一些缺点
  • 原文地址:https://blog.csdn.net/qq_42517220/article/details/126722420