我们知道,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中也是可用的。