前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >MongoDB 高级查询 aggregate 聚合管道

MongoDB 高级查询 aggregate 聚合管道

作者头像
越陌度阡
发布于 2020-11-26 04:30:01
发布于 2020-11-26 04:30:01
2.1K00
代码可运行
举报
运行总次数:0
代码可运行

1. MongoDB 聚合管道简介

使用聚合管道可以对集合中的文档进行变换和组合,常用于多表关联查询、数据的统计。

db.COLLECTION_NAME.aggregate() 方法用来构建和使用聚合管道,下图是官网给的实例,可以看出来聚合管道的用法还是比较简单的。

2. MongoDB Aggregation 管道操作符与表达式

常用的管道操作符有以下这些:

MySQLMongoDB 的聚合 对比 :

管道操作符作为 “ 键 ”, 所对应的“ 值 ”叫做管道表达式, 如 {$match:{status:"A"}} , $match 称为管道操作符,而 status:"A"称为管道表达式,每个管道表达式是一个文档结构,它是由字段名、字段值、和一些表达式操作符组成的,常用的表达式操作符有以下这些。

3. 模拟数据

为了说明每个管道操作符的作用,将以下面数据为参考,分别有order和order_item两个集合。

order集合里的数据

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
    "_id": ObjectId("5e6f15c1eb57cc45bde8130b"),
    "order_id": "1",
    "uid": 10,
    "trade_no": "111",
    "all_price": 100,
    "all_num": 2
}
{
    "_id": ObjectId("5e6f15cbeb57cc45bde8130c"),
    "order_id": "2",
    "uid": 7,
    "trade_no": "222",
    "all_price": 90,
    "all_num": 2
}
{
    "_id": ObjectId("5e6f15d4eb57cc45bde8130d"),
    "order_id": "3",
    "uid": 9,
    "trade_no": "333",
    "all_price": 20,
    "all_num": 6
}

order_item集合里的数据

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
    "_id": ObjectId("5e6f15dbeb57cc45bde8130e"),
    "order_id": "1",
    "title": "商品鼠标 1",
    "price": 50,
    "num": 1
}
{
    "_id": ObjectId("5e6f15e2eb57cc45bde8130f"),
    "order_id": "1",
    "title": "商品键盘 2",
    "price": 50,
    "num": 1
}
{
    "_id": ObjectId("5e6f15e8eb57cc45bde81310"),
    "order_id": "1",
    "title": "商品键盘 3",
    "price": 0,
    "num": 1
}
{
    "_id": ObjectId("5e6f15f1eb57cc45bde81311"),
    "order_id": "2",
    "title": "牛奶",
    "price": 50,
    "num": 1
}
{
    "_id": ObjectId("5e6f15faeb57cc45bde81312"),
    "order_id": "2",
    "title": "酸奶",
    "price": 40,
    "num": 1
}
{
    "_id": ObjectId("5e6f1603eb57cc45bde81313"),
    "order_id": "3",
    "title": "矿泉水",
    "price": 2,
    "num": 5
}
{
    "_id": ObjectId("5e6f160aeb57cc45bde81314"),
    "order_id": "3",
    "title": "毛巾",
    "price": 10,
    "num": 1
}

4. 管道操作符 $project

修改文档的结构,可以用来重命名、增加或删除文档中的字段。

例:要求查找 order 集合, 只返回文档中 trade_no 和 all_price 字段。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
db.order.aggregate([
    {
        $project:{ trade_no:1, all_price:1 }
    }
])

执行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{ "_id" : ObjectId("5e6f15c1eb57cc45bde8130b"), "trade_no" : "111", "all_price" : 100 }

{ "_id" : ObjectId("5e6f15cbeb57cc45bde8130c"), "trade_no" : "222", "all_price" : 90 }

{ "_id" : ObjectId("5e6f15d4eb57cc45bde8130d"), "trade_no" : "333", "all_price" : 20 }

5. 管道操作符 $match

用于过滤文档,用法类似于 find() 方法中的参数。

例:要求查找 order 集合,只返回文档中 trade_no 和 all_price 字段,并只显示 all_price 大于等于90的记录。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
db.order.aggregate([
    { 
        $project: { trade_no: 1, all_price: 1}
    },
    { 
        $match: {
            "all_price": {$gte: 90}
        }
    }
])

执行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{ "_id" : ObjectId("5e6f15c1eb57cc45bde8130b"), "trade_no" : "111", "all_price" : 100 }

{ "_id" : ObjectId("5e6f15cbeb57cc45bde8130c"), "trade_no" : "222", "all_price" : 90 }

6. 管道操作符 $group

将集合中的文档进行分组,可用于统计结果。

例:统计每个订单的订单数量,按照订单号分组。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
db.order_item.aggregate([
    {   
        $group: 
            {_id: "$order_id", total: {$sum: "$num"}
        }
    }
])

执行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{ "_id" : "2", "total" : 2 }

{ "_id" : "3", "total" : 6 }

{ "_id" : "1", "total" : 3 }

7. 管道操作符 $sort

将集合中的文档进行排序。

例:要求查找 order 集合, 只返回文档中 trade_no 和 all_price 字段,只显示 all_price 大于等于90的记录,并以all_price进行降序排列。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
db.order.aggregate([
    { 
        $project: { trade_no: 1, all_price: 1}
    },
    { 
        $match: {
            "all_price": {$gte: 90}
        }
    },
    { 
        $sort: {"all_price": -1}
    }
])

执行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{ "_id" : ObjectId("5e6f15c1eb57cc45bde8130b"), "trade_no" : "111", "all_price" : 100 }

{ "_id" : ObjectId("5e6f15cbeb57cc45bde8130c"), "trade_no" : "222", "all_price" : 90 }

8. 管道操作符 $limit

限制查询结果的数量。

例:要求查找 order 集合,只返回文档中 trade_no 和 all_price 字段,只显示 all_price 大于等于90的记录,以all_price进行降序排列,并只显示1条记录。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
db.order.aggregate([
    { 
        $project: { trade_no: 1, all_price: 1}
    },
    { 
        $match: {
            "all_price": {$gte: 90}
        }
    },
    { 
        $sort: {"all_price": -1}
    },
    { 
        $limit: 1
    }
])

执行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{ "_id" : ObjectId("5e6f15c1eb57cc45bde8130b"), "trade_no" : "111", "all_price" : 100 }

9. 管道操作符 $skip

对查询结果跳过几条记录进行显示。

例:要求查找 order 集合,只返回文档中 trade_no 和 all_price 字段,只显示 all_price 大于等于90的记录,以 all_price 进行降序排列,并跳过1条记录显示其结果。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
db.order.aggregate([
    { 
        $project: { trade_no: 1, all_price: 1}
    },
    { 
        $match: {
            "all_price": {$gte: 90}
        }
    },
    { 
        $sort: {"all_price": -1}
    },
    { 
        $skip: 1
    }
])

执行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{ "_id" : ObjectId("5e6f15cbeb57cc45bde8130c"), "trade_no" : "222", "all_price" : 90 }

10. 管道操作符 $lookup

对要查询的结果时行多表关联查询。

例:查询 order 集合,关联到order_item集合,将 order 中 order_id 与 order_item 中order_id 相同的记录显示出来,并将结果取名为 items。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
db.order.aggregate([
    { 
        $lookup: { 
            from: "order_item", 
            localField: "order_id", 
            foreignField: "order_id", 
            as: "items"
        }
    }
])

执行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
    "_id": ObjectId("5e6f15c1eb57cc45bde8130b"),
    "order_id": "1",
    "uid": 10,
    "trade_no": "111",
    "all_price": 100,
    "all_num": 2,
    "items": [
        {
            "_id": ObjectId("5e6f15dbeb57cc45bde8130e"),
            "order_id": "1",
            "title": "商品鼠标 1",
            "price": 50,
            "num": 1
        },
        {
            "_id": ObjectId("5e6f15e2eb57cc45bde8130f"),
            "order_id": "1",
            "title": "商品键盘 2",
            "price": 50,
            "num": 1
        },
        {
            "_id": ObjectId("5e6f15e8eb57cc45bde81310"),
            "order_id": "1",
            "title": "商品键盘 3",
            "price": 0,
            "num": 1
        }
    ]
}
{
    "_id": ObjectId("5e6f15cbeb57cc45bde8130c"),
    "order_id": "2",
    "uid": 7,
    "trade_no": "222",
    "all_price": 90,
    "all_num": 2,
    "items": [
        {
            "_id": ObjectId("5e6f15f1eb57cc45bde81311"),
            "order_id": "2",
            "title": "牛奶",
            "price": 50,
            "num": 1
        },
        {
            "_id": ObjectId("5e6f15faeb57cc45bde81312"),
            "order_id": "2",
            "title": "酸奶",
            "price": 40,
            "num": 1
        }
    ]
}
{
    "_id": ObjectId("5e6f15d4eb57cc45bde8130d"),
    "order_id": "3",
    "uid": 9,
    "trade_no": "333",
    "all_price": 20,
    "all_num": 6,
    "items": [
        {
            "_id": ObjectId("5e6f1603eb57cc45bde81313"),
            "order_id": "3",
            "title": "矿泉水",
            "price": 2,
            "num": 5
        },
        {
            "_id": ObjectId("5e6f160aeb57cc45bde81314"),
            "order_id": "3",
            "title": "毛巾",
            "price": 10,
            "num": 1
        }
    ]
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/03/16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
【小码匠自习室】让错误成为孩子进步的阶梯
碎碎念 今天梳理了这篇文章,同一个地方只能跌一次跟头,再重复错误肯定被老码农敲脑袋 梳理这篇文章源于3月份参加NOI Online测试赛没有全文比较输出文件内容,只是对比了几个值,导致爆零( ̄﹏ ̄;) 标题是老码农起的,心灵鸡汤太多了,以后想管他叫”唐鸡汤“了。(*^_^*) 准备测试文件 mode_ex1.ans 4 1 5 1 4 2 4 8 2 1 2 3 4 5 mode_ex1-2.ans 修改了第13行数据:4 -> 6 4 1 5 1 4 2 4 8 2 1 2 3 6 5 mode_ex
小码匠
2022/08/08
3800
Linux 命令(119)—— diff 命令
如果给定的文件名是 -,表示从标准输入读取内容。如果给定的文件是目录,则将会比较该目录中具有相同文件名的文件,默认情况下不会对其子目录文件进行任何比较操作。
恋喵大鲤鱼
2020/02/20
1.6K0
python 比较两个目录 脚本
""" ################################################################################ Usage: "python diffall.py dir1 dir2". Recursive directory tree comparison: report unique files that exist in only dir1 or dir2, report files of the same name in dir1 and dir2 with differing contents, report instances of same name but different type in dir1 and dir2, and do the same for all subdirectories of the same names in and below dir1 and dir2. A summary of diffs appears at end of output, but search redirected output for "DIFF" and "unique" strings for further details. New: (3E) limit reads to 1M for large files, (3E) catch same name=file/dir, (4E) avoid extra os.listdir() calls in dirdiff.comparedirs() by passing results here along. ################################################################################ """
用户5760343
2022/05/13
7760
Linux-diff和diff3命令
将目录/usr/li下的文件”test.txt”与当前目录下的文件”test.txt”进行比较,输入如下命令:
小小工匠
2021/08/16
1.6K0
【linux命令讲解大全】007.现代技术中的差异比较工具——diff
diff命令在最简单的情况下,用于比较给定的两个文件的不同。如果使用 “-” 代替 “文件” 参数,则要比较的内容将来自标准输入。diff命令以逐行的方式比较文本文件的异同处。如果该命令指定进行目录的比较,则将会比较该目录中具有相同文件名的文件,而不会对其子目录文件进行任何比较操作。
全栈若城
2024/03/02
4910
dig、diff命令详解
@<服务器地址>:指定进行域名解析的域名服务器; -b<ip地址>:当主机具有多个IP地址,指定使用本机的哪个IP地址向域名服务器发送域名查询请求; -f<文件名称>:指定dig以批处理的方式运行,指定的文件中保存着需要批处理查询的DNS任务信息; -P:指定域名服务器所使用端口号; -t<类型>:指定要查询的DNS数据类型; -x<IP地址>:执行逆向域名查询; -4:使用IPv4; -6:使用IPv6; -h:显示指令帮助信息。
菲宇
2019/06/13
1.2K0
git diff与linux diff的输出格式之unified format
前面有一篇文章《一个有些意思的项目--文件夹对比工具(一)》,里面简单讲了下diff算法之--Myers算法。
低级知识传播者
2022/11/16
2.1K0
git diff与linux diff的输出格式之unified format
diff命令
diff命令能够比较给定的两个文件的不同,如果使用-代替文件参数,则要比较的内容将来自标准输入,diff命令是以逐行的方式比较文本文件的异同处,如果该命令指定进行目录的比较,则将会比较该目录中具有相同文件名的文件,而不会对其子目录文件进行任何比较操作。
WindRunnerMax
2020/08/27
1.2K0
diff命令
接手别人的工作,想把一些操作集成到ansible管理,但是因为之前同事没留下任何文档,只能自己摸着石头过河。编写playbook要清楚某些配置文件做了哪些改动,使用diff命令,让类似文件比较的工作更加高效。
阿dai学长
2020/04/10
1.1K0
Linux之diff命令
原文链接:https://rumenz.com/rumenbiji/linux-diff.html
入门笔记
2021/07/22
1.6K0
Python 自动化业务服务监控
使用diffie模块实现文件内容差异对比。dmib作为 Python的标准库模块, 无需安装,作用是对比文本之间的差异,且支持输出可读性比较强的HTML文档,与 Linux 下的dif命令相似。我们可以使用 diffie对比代码、配置文件的差别,在版本控制方面是非 常有用。 Python3.x或更高版本默认自带 diffie模块,无需额外安装。
王瑞MVP
2022/12/28
4230
Linux 使用 diff 分栏对比文本差异
使用 -y 表示两列查看,使用 -W 设定宽度,这样就可以在终端里分栏查看文件差异:
宋天伦
2023/10/20
4780
Linux 使用 diff 分栏对比文本差异
linux比较两个目录的差异
原文链接:https://rumenz.com/rumenbiji/linux-compare-dir.html
入门笔记
2021/11/28
3K0
第五章:操作文件和目录
At this point, we are ready for some real work! This chapter will introducethe following commands:
砖业洋__
2023/05/06
2040
linux diff
diff 命令是 linux上非常重要的工具,用于比较文件的内容,特别是比较两个版本不同的文件以找到改动的地方。diff在命令行中打印每一个行的改动。最新版本的diff还支持二进制文件。diff程序的输出被称为补丁 (patch),因为Linux系统中还有一个patch程序,可以根据diff的输出将a.c的文件内容更新为b.c。diff是svn、cvs、git等版本控制工具不可或缺的一部分。
用户5760343
2022/05/20
1.5K0
linux每日命令(33):diff命令
diff 命令是 linux上非常重要的工具,用于比较文件的内容,特别是比较两个版本不同的文件以找到改动的地方。diff在命令行中打印每一个行的改动。最新版本的diff还支持二进制文件。diff程序的输出被称为补丁 (patch),因为Linux系统中还有一个patch程序,可以根据diff的输出将a.c的文件内容更新为b.c。diff是svn、cvs、git等版本控制工具不可或缺的一部分。
用户1214487
2018/12/24
1.5K0
[Linux][4_文件,打包和用户管理]
Linux系统中使用以下命令来查看文件的内容:     cat 由第一行开始显示文件内容     tac 从最后一行开始显示,可以看出 tac 是 cat 的倒著写!     nl 显示的时候,顺道输出行号!     more 一页一页的显示文件内容     less 与 more 类似,但是比 more 更好的是,他可以往前翻页!     head 只看头几行     tail 只看尾巴几行     wc 统计文件行数
玖柒的小窝
2021/10/23
5600
Linux常用命令
1:  shutdown [root@cairui ~]# shutdown --help Usage: shutdown [OPTION]... TIME [MESSAGE]  #使用 Bring the system down. Options: -r reboot after shutdown            #重启,也可以直接使用 reboot 命令 -h halt or power
用户1173509
2022/05/09
7530
Linux常用命令
11.Linux文件管理命令---diff比较两个文件
下面是 GNU 所接受的 diff 所有选项的概要。大多数选项有两个相同的名字,一个是单个 地跟在“-”后面的字母,另一个是由“--”引出的长名字。多个单字母选项(除非它们产生歧 义)能够组合为单行的命令行语法,-ac 等同于 -a –c。长命名的选项能被缩短到它们的名字的 任何唯一的前缀。用 和 括起来显示产生歧义的选项。
鱼多多
2025/01/03
1670
11.Linux文件管理命令---diff比较两个文件
Linux常用命令
Linux中许多常用命令是必须掌握的,这里将我学linux入门时学的一些常用的基本命令分享给大家一下,希望可以帮助你们。
鱼找水需要时间
2023/02/16
5.2K0
相关推荐
【小码匠自习室】让错误成为孩子进步的阶梯
更多 >
LV.1
新浪网技术(中国)有限公司PHP开发工程师
目录
  • 1. MongoDB 聚合管道简介
  • 2. MongoDB Aggregation 管道操作符与表达式
  • 3. 模拟数据
  • 4. 管道操作符 $project
  • 5. 管道操作符 $match
  • 6. 管道操作符 $group
  • 7. 管道操作符 $sort
  • 8. 管道操作符 $limit
  • 9. 管道操作符 $skip
  • 10. 管道操作符 $lookup
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文