[学习笔记] MongoDB
MongoDB学习笔记
基本概念
MongoDB是一个开源、高性能、无模式的文档型数据库,由C++语言编写,是一个介于关系型数据库和非关系型数据库之间的产品,是非关系型数据库当中功能最丰富、最像关系型数据库的
MongoDB支持的数据结构非常松散,是类似JSON的BSON(Binary-JSON)格式,因此它可以存储比较复杂的数据类型
MongoDB中的记录是一个文档,是一个由字段和值对(filed:value)组成的数据结构。MongoDB文档类似于JSON对象,即一个文档认为就是一个对象。字段的数据类型是字符型,它的值除了使用基本的一些类型外,还可以包括其他文档、普通数组和文档数组
MongoDB最大特点就是它支持的查询语言非常强大,语法有点类似于面向对象的查询语言,几乎可实现类似关系型数据库单表查询的绝大部分功能,而且还支持对数据建立索引
业务应用场景
传统的关系型数据库在数据操作的三高需求以及应对Web2.0的网站需求面前略显乏力:
- High performance:对数据库高并发读写的需求
- Huge Storage:对海量数据的高效率存储和访问的需求
- High Scalability & High Availability:对数据库的高可扩展性和高可用性的需求
MongoDB具体应用场景
- 社交场景。使用MongoDB存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能
- 游戏场景。使用MongoDB存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、高效率存储和访问
- 物流场景。使用MongoDB存储订单信息,订单状态在运送过程中会不断更新,以MongoDB内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来
- 物联网场景。使用MongoDB存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析
- 视频直播。使用MongoDB存储用户信息、点赞互动信息等
这些应用场景中,数据操作方面的共同特点是:数据量大、读写操作频繁、低价值数据对事务性要求不高。对于这样的数据,更适合使用MongoDB进行存储
什么时候选择使用MongoDB
- 应用不需要事务和复杂JOIN支持
- 需求会变、数据模型无法确定、想快速迭代开发的新应用
- 需要大量的地理位置查询、文本查的应用
- 需要99.999%高可用的应用
- 需要存储的数据不丢失的应用
- 需要TB甚至PB级别数据存储的应用
- 需要3000以上甚至更高的读写QPS的应用
术语对照
| SQL术语/概念 | MongoDB术语/概念 | 说明 |
|---|---|---|
| database | database | 数据库 |
| table | collection | 数据库表/集合 |
| row | document | 数据记录行/文档 |
| column | field | 数据字段/域 |
| index | index | 索引 |
| table joins | 表连接,MongoDB不支持 | |
| 嵌入文档 | MongoDB通过嵌入式文档来替代多表连接 | |
| primary key | primary key | 主键,MongoDB自动将_id字段设置为主键 |
存储的数据类型
MongoDB的最小存储单位就是文档对象(document),文档对象对应于关系型数据库的行。数据在MongoDB中以BSON(Binary-JSON)文档的格式存储在磁盘上
BSON,Binary Serialized Document Format,是一种类似JSON的一种二进制形式的存储格式,支持内嵌的文档对象和数据对象,但BSON有JSON没有的一些数据类型,比如Date、Bin Date
BSON中,除了基本JSON类型:string、integer、boolean、double、null、array和object,Mongo还使用了特殊的数据类型,这些类型包括date、object id、binary data、regular expression和code
基本命令
打开一个连接到本地实例的MongoShell
mongosh
显示当前MongoDB实例中的所有数据库
show databases
show dbs
切换到数据库<dbname>
use <dbname>
显示当前使用中的数据库名称
db
清屏
cls
显示当前数据库中的所有集合
show collections
删除当前的数据库
db.dropDatabase()
退出mongosh对话
exit
创建/插入文档
在集合中插入一个新的文档
insertOne
db.users.insertOne({name:"Donk"})
在集合中插入多个新的文档
insertMany
db.users.insertMany([{name:"Donk"},{name:"Shiro"},{name:"Niko"}])
查找
查询所有的文档
find
db.users.find()
查询所有满足参数对象<filterObject>中指定过滤条件的数据
find(<filterObject>)
db.users.find({name:"Donk"})
查询所有满足参数对象<filterObject>中指定过滤条件的数据,并且只返回<selectObject>中指定的字段
db.find(<filterObject>, <selectObject>)
db.users.find({name:"Donk"}, {name:1, age:1})
与find用法相同,找到满足过滤条件的对象,但只返回第一条
findOne()
db.users.findOne({level:1})
返回满足条件的记录的数量
countDocuments
使用给定的字段按照升序或者降序来排序
sort
限定只返回给定数量的文档
limit
从头开始跳过给定数值的文档
skip
更新
更新满足条件的第一个文档
updateOne
更新满足条件的所有文档
updateMany
替换满足条件的第一个文档
replaceOne
通过传入的文档替换已有文档或插入一个新的文档
save
只更新文档中$set指定的字段,不会影响其他字段
$set
用于递增或递减文档中指定字段值的操作符
$inc
更新某个字段的名称
$rename
删除一个字段
$unset
将值加入一个数组中,不会判断是否有重复的值
$push
将值从一个数组中移除
$pull
将值加入一个数组中,会判断是否有重复的值,若重复则不加入
$addToSet
删除
删除满足条件的第一个文档
deleteOne
删除满足条件的所有文档
deleteMany
过滤条件
| $eq | 等于 |
|---|---|
| $ne | 不等于 |
| $gt/$gte | 大于/大于等于 |
| $lt/$lte | 小于/小于等于 |
| $in | 值在指定值列表中,就返回该文档 |
| $nin | 值不等于指定值列表中的任何一个,就返回该文档 |
| $and | 检查复数条件是否均为真 |
| $or | 检查复数条件中是否有一个为真 |
| \(not | 将\)not里面的过滤条件取反 | |
| $exists | 检查一个字段是否存在 |
| $expr | 在不同的字段之间做比较 |
聚合
| $sum | 计算总和 |
|---|---|
| $avg | 计算平均值 |
| $min | 获取最小值 |
| $max | 获取最大值 |
| $push | 将值加入一个数组中,不会判断是否有重复的值 |
| $first | 获取第一个文档数据 |
| $last | 获取最后一个文档数据 |

浙公网安备 33010602011771号