MongoDB 高手课
唐建法(TJ)
Tapdata CTO、MongoDB 中文社区主席、前 MongoDB 大中华区首席架构师
19351 人已学习
新⼈⾸单¥59
课程目录
已完结/共 53 讲
MongoDB 高手课
登录|注册
留言
41
收藏
沉浸
阅读
分享
手机端
回顶部
当前播放: 09 | 实验:聚合查询
00:00 / 00:00
高清
  • 高清
1.0x
  • 2.0x
  • 1.5x
  • 1.25x
  • 1.0x
  • 0.75x
  • 0.5x
网页全屏
全屏
00:00
付费课程,可试看
01 | 课程介绍
02 | 内容综述
03 | 认识文档数据库MongoDB
04 | MongoDB特色及优势
05 | 实验:安装MongoDB
06 | MongoDB基本操作
07 | 实验:Hello World程序开发
08 | 聚合查询
09 | 实验:聚合查询
10 | 复制集机制及原理
11 | 实验:搭建MongoDB复制集
12 | MongoDB全家桶
13 | 模型设计基础
14 | JSON文档模型设计特点
15 | 文档模型设计之一:基础设计
16 | 文档模型设计之二:工况细化
17 | 文档模型设计之三:模式套用
18 | 设计模式集锦
19 | 事务开发:写操作事务
20 | 事务开发:读操作事务之一
21 | 事务开发:读操作事务之二
22 | 事务开发:多文档事务
23 | Change Stream
24 | MongoDB开发最佳实践
25 | 分片集群机制及原理
26 | 分片集群设计
27 | 实验:分片集群搭建及扩容
28 | MongoDB监控最佳实践
29 | MongoDB备份与恢复
30 | 备份与恢复操作
31 | MongoDB安全架构
32 | MongoDB安全加固实践
33 | MongoDB索引机制(一)
34 | MongoDB索引机制(二)
35 | MongoDB读写性能机制
36 | 性能诊断工具
37 | 高级集群设计:两地三中心
38 | 实验:搭建两地三中心集群
39 | 高级集群设计:全球多写
40 | MongoDB上线及升级
41 | MongoDB应用场景及选型
42 | MongoDB典型案例(一)
43 | MongoDB典型案例(二)
44 | 关系型数据库迁移
45 | 数据库迁移方式及工具
46 | Oracle迁移实战
47 | MongoDB + Spark实时大数据
48 | MongoDB + Spark连接实战
49 | MongoDB SQL套接件
50 | MongoDB与微服务
51 | MongoDB与数据中台
52 | MongoDB数据中台案例
53 | 结果测试&结束语
登录 后留言

全部留言(41)

  • 最新
  • 精选
第一装甲集群司令克莱斯特
我们业务场景就遇到了聚合查询的情况,很简单,但是对于小白也很费脑筋。作为网关流量统计需求,接口需要给前端返回每日00:00:00 ~ 23:59:59这一天内,字段messageType分别为01 02 03 04 ,四种业务意义的请求数量,请老师明示怎么动态取每天的date,然后返回的结果分条显示当天24小时之内,不同值messageType得请求数量count(messageType)。

作者回复: 这个问题需要一些时间,所以回复晚了一点。 ## 数据模型 测试数据: ```javascript db.test.insertMany([ { messageType: '01', date: ISODate("2019-01-01T01:15:42Z") // 其他字段 }, { messageType: '01', date: ISODate("2019-01-01T01:17:42Z") }, { messageType: '02', date: ISODate("2019-01-17T01:17:42Z") }, { messageType: '02', date: ISODate("2019-01-17T02:17:42Z") }, ]) ``` ## 解决思路 1. 从日期中提取日期和小时。这里如果有必要,需要考虑时区问题。如果考虑时区问题,则需要3.6以上版本支持; 1. 按日期、小时分组聚合; 使用到的运算符: - [$dateToString](https://docs.mongodb.com/manual/reference/operator/aggregation/dateToString/) - [$year](https://docs.mongodb.com/manual/reference/operator/aggregation/year/) - [$month](https://docs.mongodb.com/manual/reference/operator/aggregation/month/) - [$dayOfMonth](https://docs.mongodb.com/manual/reference/operator/aggregation/dayOfMonth/) ## 聚合语句 ```javascript db.test.aggregate([ // 过滤条件(如果有) { $match: { date: { $gte: ISODate("2019-01-01T00:00:00Z"), $lt: ISODate("2019-02-01T00:00:00Z"), } } }, // 映射出日期和小时 { $project: { date: { $dateToString: { date: "$date", format: "%Y-%m-%d", timezone: "+08:00" } }, hour: { $hour: "$date" }, messageType: 1 } }, { // 按日期、小时、messageType分组计数 $group: { _id: { date: "$date", hour: "$hour", messageType: "$messageType" }, count: { $sum: 1 } } } ]); ```

2019-11-13
2
33
fedwing
还有一个小建议,希望老师更多讲讲为什么这么设计,内部实现原理,方便真正理解mongo,而不只是会用!目前我在国内一线游戏大厂开发一款算是爆款的游戏,随着游戏数据的增多,暴露出一些mongo问题,用的是3.2的mongo,且没有切wt,目前想要调整版本和存储引擎,所以想要深入了解mongo,想要成为mongo高手,期待老师赶紧更新

作者回复: 谢谢。后续章节会涉及一些设计方面的。但是本课程的目标确实是偏应用方面多一点。源码底层内容太多,可能需要另外的课程来覆盖。

2019-11-15
8
唐朝农民
老师问个实际使用中有点纠结的问题,你的DEMO 中,很多数据基本上都是冗余存储到一个collection上面,比如 订单中的商品或国家直接存储的是对应的名称,而我们使用MySql 时通常存储的是 对应的ID,这样mysql 的查询往往需要join 多张表才能满足用户的查询需求,mongo 这样的冗余存储则不需要,但是这也带来一个问题,就是数据一致性问题,当我需要修改某个商品的名称时对应该商品的所有关联数据都要修改,如果像关系型数据库那样主外键设计,那可能还是需要先设计好对应表之间的关系,并且查询同样要聚合查询,那岂不又失去了MongoDb 的文档灵活性,相比mysql还有那么大的优势吗?目前我们项目中只有类似日志这样永远不会变的数据用的MongoDB存储,还请老师解答我的疑惑

作者回复: 你可以打破常规思维考虑。国家的名称你多长时间需要改一次呢?当然,商品名称修改频率会略高一些,但也是低频动作。MongoDB已经提供多表多行事务来保证修改的一致性。另外如果是经常要改的内容,也还是可以按照关系设计,并不是绝对要放到一张表里面。

2019-11-14
5
第一装甲集群司令克莱斯特
Mongo Compass官方的就是好用,大而全,我们还在用Mongo Booster,Mongo Compass中的Export To Language,帮我解决了大问题,在Mysql聚合查询语句翻译成MQL,再转换成Java 方式,快速高效,不用去翻MongoaTemplate API了.

作者回复: 非常棒!

2019-11-13
2
4
vachel
老师,感谢精彩的分享!请教一下聚合查询的性能问题,能否结合您的业务场景自己数据量说明一下 ?非常感谢!

作者回复: 这个范围很广。我们的客户中最大的有100TB的数据量上做聚合的(Amadeus)。当然那个是32台物理服务器和288个微分片的架构,比较复杂了。 通常来说MongoDB有可以在内存做计算的特性,如果你可以把你的数据都放在内存,那么聚合运算的性能大概率可以不错。 如果你有数千万数亿以上的行数要做扫描性汇聚,又是跑在机械盘,索引又没有优化,那么有可能是分钟级的聚合计算性能。

2019-11-13
3
3
***
你好老师,我在做聚合练习的时候,有一个问题需要请教你。 我的文档结构是这样的: [ { "group":"A", "status":"SUCCESS" } { "group":"A", "status":"SUCCESS" }, { "group":"A", "status":"FAILURE" }, { "group":"B", "status":"SUCCESS" } { "group":"B", "status":"FAILURE" } ] 聚合期望结果 [{ group:"A", SUCCESS:3 FAILURE:1 }, { group:"B", SUCCESS:1, FAILURE:1 } ] 我现在只能到这种程度: {$group: { _id: "$group", result: {$push:{"res":"$status"}} }} 还请老师指教。

作者回复: 需要使用条件判断,有一点点绕: db.test.aggregate([ { $group: { _id: "$group", success: { $sum: { $cond: { if: { $eq: [ "$status", "SUCCESS" ] }, then: 1, else: 0 } } }, failure: { $sum: { $cond: { if: { $eq: [ "$status", "FAILURE" ] }, then: 1, else: 0 } } } } } ])

2020-06-10
2
2
老师请问下,如果我有若干年的毫秒级的价格数据,我想对每条数据增加一个字段,字段内容为当前时间到接下来1000毫秒之间的数据的价格字段的最大值,怎么实习呢?

作者回复: MongoDB里面貌似实现不了这么高级的计算,可能只能拉到内存里。这么大的量的话,要用到spark来做并发计算然后再把结果写回去mongodb。

2019-11-28
2
2
齐宝金
老师好,请问下对于: rs1:PRIMARY> db.oplog.rs.findOne().ts Timestamp(1574326231, 1) 执行db.oplog.rs.findOne().ts 时,返回值是Timestamp(1574326231, 1)。而我的需求是指获取1574326231,如果想获取1574326231值,有现成的函数吗,还是自己解析

作者回复: > Timestamp(1574326231, 1).getTime() 157432623

2019-11-21
3
2
YoKate
我的数据库某张表有2.2M的数据,我需要从这些数据里面计算出想要的数据,比如某个产品的销售额度。这个用聚合会把数据库查崩么》

作者回复: 这么没信心。。。 如果计算的结果太大, 超过16MB,或者需要在内存进行排序或其他计算的时候超过100MB,聚合操作会失败。通常的做法是避免对非索引字段进行排序,或者使用allowDiskUse选项来突破100MB的限制。 另外,考虑在从节点上进行这样的聚合操作。否则会影响其他的数据库操作业务。

2019-12-16
1
做聚合查询,希望把多个文档的同一字段合并在一起,这样使用第三方工具(matlab)读取时速度会明显加快,聚合过程中出现了BufBuilder attempted to grow() to 67108868 bytes, past the 64MB limit.' 在网上查了下说是mongodb单个文档的大小限制。一般遇到这个问题该这么处理呢?感觉分成多个文档虽然可行但违背想方便的读取数据这个使用初衷了呢

作者回复: 这个是MongoDB的物理限制,目前除了分文档之外没有别的解决方案。

2019-11-30
1
收起评论