(MongoDB)与SQL查询语句对比

一、背景介绍:

一句话介绍:

MongoDB与SQL常用查询语句对比文档

详细介绍:

主要用于记录MongeDB与SQL常用查询语句的对比,方便查询与简单学习。若有笔误 or 缺漏,欢迎评论补充。

文档数据库(MongoDB)介绍

MongoDB

  • 优点:速度快,分片,易扩展,没有schema带来的灵活,分布式

  • 缺点:数据大小有限制,不能无限嵌套,高内存,不支持业务复杂查询

  • 适用场景

    • 希望直接存储复杂struct或json格式的数据,不希望拆分成多个item的需求
    • 大尺寸、低价值数据存储:因为存储便宜
    • 高伸缩性场景
  • 不适合的场景

    • 高度事务性系统: 传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。
    • 有比较复杂的查询

二、常用查询语句对比:

MongoDB 基本查询的通用方式 :

db.表名.find({},{}).功能

css 复制代码
第一个{}  为条件查询    
第二个{}  为返回的列 {字段名:1}    
功能 : sort(字段:1) | skip(num) | limit(num) | count()

1.1 简单查询对照表:

名称 SQl语句 ByteDoc MongoDB )语句 备注
1. 全查询(查询全部字段信息) select * from people db.people.find()
2. 精准查询(查询部分字段信息) SELECT object_id, room_idFROM people db.people.find( {}, { "object_id" : 1, "room_id" : 1 , "_id" : 0 }) 1表示该字段显示,0表示不显示,比如这儿默认会返回主键"_id"信息,如果不想要就可以赋值为0。
3. 条件查询(查询符合条件的全字段数据) SELECT *FROM peopleWHERE status = "yes" db.people.find({ status: "yes" }) 只使用第一个花括号时,第二个可以省略。此时为全查询。
4. 条件+精准查询(查询符合条件的数据并显示部分字段) SELECT object_id, room_idFROM people WHERE status = "yes"AND ab_cluster ****= 1 db.people.find({ status: "yes" , "ab_cluster" : 1 },{"object_id" : 1, "room_id" : 1 })
5. 符号条件查询(不等于、大于、小于,存在(in)等符号条件查询) SELECT *FROM peopleWHERE status != "yes" 不等于 db.people.find({ "status": { ne: "yes"}})大于 : db.people.find({"status":{gt : "yes"}})大于等于 : db.people.find({"status":{gte : "yes"}})小于 : db.people.find({"status":{lt : "yes"}})小于等于 : db.people.find({"status":{$lte : "yes"}}) 其余操作符:Ps:字符串类型用操作符比较的字典序
6. 或 查询(查询满足部分条件的数据) SELECT *FROM peopleWHERE status = "yes"OR ab_cluster ****= 1 db.people.find({ $or: [ { "status" : "yes" } , { "ab_cluster" : 1 } ] }) 与 查询见4
7.1 模糊查询(查询object_id包含"1234"的数据) SELECT *FROM peopleWHERE object_id like "%1234%" db.people.find( { object_id: /1234/ } )或者db.people.find( { object_id: { $regex: /1234/ } } )
7.2模糊查询(查询object_id以"1234"开头的数据) SELECT *FROM peopleWHERE object_id like "1234%" db.people.find( { object_id: /^1234/ } )或者db.people.find( { object_id: { $regex: /^1234/ } } )
8.1 排序:升序(按照创建时间升序查询数据) SELECT *FROM peopleWHERE status = "yes"ORDER BY create_time ASC db.people.find( { status: "yes" } ) .sort( { "create_time": 1 } )
8.1 排序:降序(按照创建时间降序查询数据) SELECT *FROM peopleWHERE status = "yes"ORDER BY create_time DESC db.people.find( { status: "yes" } ) .sort( { "create_time": -1 } )
9. 统计(查询年龄大于30的数据数量) SELECT COUNT (*)FROM peopleWHERE age > 30 db.people.count( { age: { gt: 30 } } )或者db.people.find( { age: { gt: 30 } } ).count() 注意花括号数量和匹配关系。
10. 限制数据数量(跳过5条,查询10条数据) SELECT *FROM peopleLIMIT 10OFFSET 5 db.people.find().limit(10).skip(5) 删除.skip(5) 就是查询前十条数据
11. 去重(查询数据,当room_id相同时只保留一条) SELECT DISTINCT (room_id)FROM people db.people.aggregate( [ { group : { _id : "room_id" } } ] )或者db.people.distinct( "room_id" )

以上是基本查询的对照表,可以各种排列组合满足日常需要,但如果我们要用到分组查询,此外在分组前后需要筛选、排序、限制数量等操作就需要1.2节的聚合查询了。

1.2 聚合查询对照表:

参考文档:MongoDB 常用查询操作 - 掘金

mongodb 基本查询与高级查询 看这里就够了 - 掘金

聚合操作可以实现分组、排序、分页、多集合关联查询等,使用语法格式:

less 复制代码
db.表名.aggregate([    
    {聚合操作一},    
    {聚合操作二}
])

聚合操作 = 管道操作符,常用聚合操作以及与SQL关键字对应表如下:

大多用到聚合查询是在分组查询时,分组查询基本语法及其常用字段运算符如下:

名称 SQl语句 ByteDoc MongoDB )语句 备注
1. 统计数量(统计表中数据总数) SELECT COUNT () AS **count *FROM table db.table.aggregate( [{group: {_id: null,count: { sum: 1 }}}] ) 注意:分组符号后面还要跟花括号。其中_id表示分组字段,null表示没有指定分组字段,所以就是相当于没有分组。count是别名 or 字段名,后面跟根据该字段进行的操作(求和、求最大值等等)
2. 字段求和(统计每场直播的观看次数并累加为总观看次数) SELECT SUM (vv) AS totalVVFROM table db.table.aggregate( [{group: {_id: null,totalVV: { sum: "$vv" }}}] ) sum后面指定了字段,即按照这个字段求和。totalVV是别名。
3. 分组+统计 (按照ab实验类型分组然后统计每种实验命中个数 SELECT _id,SUM (enpool.ab_cluster) AS countFROM tableGROUP BY enpool.ab_cluster db.table.aggregate( [{group: {_id: "enpool.ab_cluster",count: { $sum: "1" }}}] ) group中的_id指定了字段,即按照这个字段分组
4. 分组后排序(按照ab实验类型分组计数后根据数量升序排序) SELECT _id,SUM ( enpool.ab_cluster) AS countFROM tableGROUP BY enpool.ab_clusterORDER BY count db.table.aggregate( [{group: {_id: "enpool.ab_cluster",count: { sum: "1" }}},{ sort: { count: 1 } }] ) sort后面指定排序字段为count,排序规则为1(升序)
5. 排序、限制数量后分组(排序后取最近送审100条数据,按照ab实验分组,然后每组计数) SELECT _id,user_id,SUM (enpool.ab_cluster) AS countFROMSELECT * FROM table ORDER BY create_time DESC LIMIT 100 )GROUP BY enpool.ab_cluster db.table.aggregate( [{ sort : { create_time : -1 } },{ limit : 100 },{group: {_id: "enpool.ab_cluster",count: { $sum: "1" }}}] ) 交换了聚合的顺序就实现了先排序后分组,所以聚合操作的顺序特别重要!
6. 分组前筛选+分组后筛选(分组前筛选状态为"yes"的数据,分组后筛选总数大于250的数据) SELECT cust_id,SUM (enpool.ab_cluster) AS countFROM tableWHERE status = 'yes'GROUP BY enpool.ab_clusterHAVING count > 250 db.table.aggregate( [{ match: { status: 'yes' } },{group: {_id: "enpool.ab_cluster",count: { sum: "enpool.ab_cluster" }}},{ match: { total: { gt: 250 } } }] ) $match:条件匹配管道,注意放在group前后的筛选时机也不同。

基本上的分组查询以及分组前后的筛选、排序、限制数量就如上所示了。如果还需要更多更进阶的查询方法,可以阅读相关文档。

注意:最终结果是按照编写时聚合操作的顺序执行!!!所以一定要注意聚合操作的顺序!比如:先limit再分组是按照limit的数量的原始数据再来分组,先分组再limit则是限制分组的数量。

1.3 真实案例演示:

举一个实际查询过程中的例子,需求如下:

查询某用户id最近的数据是否符合实验分组比例?

拆分成数据库逻辑查询语句如下:(ps:至少要20条才能看出比例区别。

根据用户id查询数据,根据创建时间倒序取20条,然后根据实验字段分组再各组求和得数量

实际查询语句如下:

db.table.aggregate(

[

{

'$match': // 先条件查询

{

"user_id": "123456789"

}

}

,

{ '$sort' : { create_time: -1 } }, // 再创建时间降序排序

{ '$limit' : 20 }, // 然后取20条数据

{

'$group': {

_id: "$cluster", // 最后根据实验字段分组

count: { $sum: 1 } // 以及按照该字段求和

}

}

]

)

相关推荐
马剑威(威哥爱编程)2 小时前
MongoDB面试专题33道解析
数据库·mongodb·面试
掘金-我是哪吒3 小时前
微服务mysql,redis,elasticsearch, kibana,cassandra,mongodb, kafka
redis·mysql·mongodb·elasticsearch·微服务
全能全知者5 小时前
docker快速安装与配置mongoDB
mongodb·docker·容器
齐 飞5 小时前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb
暮毅5 小时前
10.Node.js连接MongoDb
数据库·mongodb·node.js
齐 飞1 天前
MongoDB笔记02-MongoDB基本常用命令
前端·数据库·笔记·后端·mongodb
齐 飞1 天前
MongoDB笔记03-MongoDB索引
前端·数据库·笔记·后端·mongodb
威哥爱编程1 天前
MongoDB面试专题33道解析
数据库·mongodb·面试
r i c k2 天前
MongoDB Shell 基本命令(三)聚合管道
mongodb