我们知道,mongo 里的普通查询语句是没有分组查询功能的,如果要实现类似于关系型数据库 SQL 里的 group by 操作就要用 aggregate。遗憾的是副本集中,aggregate 操作是在主库执行(比如笔者的 3.0.3 就是这样的,据说 mongo 新版本会改善这一状况 - 将 aggregate 操作放到从库执行),这对于读写分离的副本集是不合理的,大并发时的大量慢查询操作很容易将主库给拖死。
要想提高主库性能,优化 aggregate 慢查询是一个不错的办法,但是如果能将 aggregate 换成普通查询语句进而去从库执行(实现读写分离)也不失为一个不错的优化方案。本文将以一个实战例子详解如何使用普通查询语句替代 aggregate 操作,本文示例代码均采用 go 语言实现。
				database.C(col.name).Pipe([]bson.M{
					{"$match": find},
					{"$group": bson.M{"_id": "$merId"}},
					{"$group": bson.M{"_id": "null", "total": bson.M{"$sum": 1}}},
				}).One(&total)

代码解析:find 对象是一个用于存放查询条件的 BSON map(类似于 SQL 里的 where 从句),total 是一个自定义的用于存放返回结果的结构体(类似于 JDK JDBC API 里的 ResultSet)。上述查询使用了两层 group,第一层按 merId 进行分组,第二层对第一层分组后的 merId 个数进行统计。
理解其要做的事情之后,我们可以还是按 find 的条件进行查询,调用查询结果(是一个 v2.Query 对象)的 Distinct 函数对 merId 进行分组 - 这一步实现了上述语句的第一层 group;merId 分组后我们在对这个分组执行查看长度的操作,实现上述 aggregate 中的第二层分组。go 语言示例代码如下:
		var itotal int = 0
		var res []string
		err := database.C(col.name).Find(find).Distinct("merId", &res)
		if err != nil {
			log.Errorf("fail: %s", err)
		itotal = len(res)
		total.Value = itotal

这段代码实现的功能和上述 aggregate 实现的功能是一样的,但它是在从库执行。美中不足的是要把所有符合条件的 merId 都从数据库拉到应用,之后由应用计算其长度,因为 Distinct 返回的结果是一个 error 接口,不能够计算 merId 集合的长度,但牺牲的这点应用内存和应用数据库带宽能换来 mongo 副本集主从库的读写分离,还是值得的。 我们知道,mongo 里的普通查询语句是没有分组查询功能的,如果要实现类似于关系型数据库 SQL 里的 group by 操作就要用 aggregate。遗憾的是副本集中,aggregate 操作是在主库执行(比如笔者的 3.0.3 就是这样的,据说 mongo 新版本会改善这一状况 - 将 aggregate 操作放到从库执行),这对于读写分离的副本集是不合理的,大并发时的大量慢查询操作很容易将
毫不夸张的说咱们后端工程师,无论在哪家公司,呆在哪个团队,做哪个系统,遇到的第一个让人头疼的问题绝对是数据库性能问题。如果我们有一套成熟的方法论,能让大家快速、准确的去选择出合适的 优化 方案,我相信能够快速准备解决咱么日常遇到的80%甚至90%的性能问题。 从解决问题的角度出发,我们得先了解到问题的原因;其次我们得有一套思考、判断问题的流程方式,让我们合理的站在哪个层面选择方案;最后从众多的方案里面选择一个适合的方案进行解决问题,找到一个合适的方案的前提是我们自己对各种方案之间的优缺点、场景有足够的了解,没
以下分别 使用 find 查询 aggregate 聚合 查询 以下为dao层(server/dao/cmsResourceDao.js),基于 mongo ose 查询 mongodb getModel(){ return mongo ose.model(...
上节课我们学习了如何用 pyquery 提取 HTML 中的信息,但是当我们成功提取了数据之后,该往哪里存放呢? 用文本文件当然是可以的,但文本存储不方便检索。有没有既方便存,又方便检索的存储方式呢? 当然有,本课时我将为你介绍一个文档型数据库 —— MongoDB MongoDB 是由 C++ 语言编写的非关系型数据库,是一个基于分布式文件存储的开源数据库系统,其内容存储形式类似 JSON 对象,它的字段值可以包含其他文档、数组及文档数组,非常灵活。 在这个课时中,我们就来看看 Python 3 下 M
MongoDB 是一种文档型数据库管理系统,其中的数据以BSON的格式存储在磁盘上,并 使用 MongoDB Query Language(MQL)进行 查询 。 与传统的关系型数据库管理系统(RDBMS)不同, MongoDB 使用 SQL语言。但是,MQL具有类似于SQL语言的结构,可以 使用 类似于SQL语言的语法进行 查询 。 例如,下面是一个 使用 MQL 查询 MongoDB 数据库的示例: db.products.find( { "price": { $gt: 50 } } ) 该 查询 将返回“products”集合中价格大于50美元的所有文档。 需要注意的是, MongoDB 也支持 使用 Aggregation Pipeline(聚合管道)来进行复杂的数据聚合 操作 ,该功能在MQL中也是可用的。