type
status
date
slug
summary
tags
category
icon
password
Property
Aug 9, 2024 11:59 AM
01 认识MongoDB
1.什么是MongoDB?
MongoDB和MySQL一样都是数据库,都是存储数据的仓库,
不同的是MySQL是关系型数据库,而MongoDB是非关系型数据库
2.什么是非关系型数据库?
2.1在’关系型数据库’中,数据都是存储在表中的,对存储的内容有严格的要求
因为在创建表的时候我们就己经规定了表中有多少个字段,
已经规定了每个字段将来要存储什么类型数据,
已经规定了每个字段将来是否可以为空,是否必须唯一等等
2.2在’非关系型数据库’中,没有表概念,所以存储数据更加灵活
因为不需要创建表,所以也没有规定有哪些字段,
也没有规定每个字段数据类型,
也没有规定每个字段将来是否可以为空,是香必须唯一等等
2.3“关系型数据库”由于操作的都是结构化的数据,所以我们需要使用结构化语言SQL来操作
2.4 ”非关系型数据库“由于数据没有严格的结构要求, 所以无需使用SQL来操作
3. 什么是MongoDB?
存储文档(BSON) 的非关系型数据库
5.企业开发如何选择?
关系型数据库和非关系型数据库之间并不是替代关系,而是互补关系
所以在企业开发中大部分情况是结合在一起使用。
对于数据模型比较简单、数据性能要求较高、数据灵活性较强的数据,我们存储到非关系型数据库中
相反则存储到关系型数据库中
具体使用:会在项目中实现
02 安装MongoDB
03 MongoDB 快速入门
1。连接MongoDB服务器
通过mongo连接MongoDB服务器
2.查看数据库
#和MySQL中的 show databases;指令一样
3.创建数据库
#和MySQL中的 use 指令一样,只不过MongoDB中的use数据库不存在会自动创建
4.查看数据库中有哪些集合
#和MySQL中的 show tables:指令一样
5.创建集合
6.插入数据
7.查询一个集合
8.删除一个集合
9.删除一个数据库
04 MongoDB 主键
1.主键
MongoDB的主键和MySQL一样,也是用于保证每一条数据唯一性的
和MySQL不同的是,MongoDB中的主键无需明确指定
- 每一个文档被添加到集合之后,MongoDB都会自动添加主键
- MongoDB中文档主键的名称叫做_id
默认情况下文档主键是一个Ob jectld类型的数据
Objectld类型是一个12个字节的BSON类型字符串 (5e8c5ae9-c9d35e-759b-d6847d)
- 4字节是存储这条数据的时间戳
- 3字节的存储这条数据的那台电脑的标识符
- 2字节的存储这条数据的MongoDB进程id
- 3字节是计数器
2.为什么要使用ObjectId类型数据作为主键?
2.1 MongoDB是支持’横向扩展’的数据库
横向扩展是指’增加数据库服务器的台数
纵向扩展是指’增加数据库库服务器的配置”
过去一个数据库只能安装在一台电脑上,但是每台电脑的性能是有峰值的。一旦达到峰值就会导致服务器卡顿、宕机、重启等问题。所以过去为了防止如上问题的出现、我们只能不断的纵向扩展。也就是不断的提升服务器的配置,让服务器能处理更多的请求。但是纵向扩展也是有峰值的,一台电脑的配置不可能无限提升。所以为了解决这个问题就有了分布式数据库(横向扩展)。
分布式数据库是指可以在多台电脑上安装数据库,然后把多台电脑组合成一个完整的数据库, 在分布式数据库中,我们可以通过不断同步的方式,让多台电脑都保存相同的内容当用户请求数据时,我们可以把请求派发给不同的数据库服务器处理当某一台服务器宕机后,我们还可以继续使用其它服务器处理请求。从而有效的解决了单台电脑性能峰值和单台电脑宕机后服务器不能使用的问题
2.2为什么要使用ObjectId类型数据作为主键?
正是因为MongoDB是一个分布式数据库,正是因为分布式数据库可以把请求派发给不同的服务器,所以第一次插入数据时,我们可能派发给了A服务器,插入到了A服务器的数据库中。但是第二次插入数据时,我们又可能派发给了B服务器,插入到了B服务器的数据库中。
但是B服务器此时并不知道A服务器当前的主键值是多少,如果通过MySQL中简单的递增来保证数据的唯一性。 那么将来在多台服务器同步数据的时候就会出现重复的情况,所以MongoDB的主键并没有使用简单的递增,而是使用了ObjectId类型数据作为主键。
3是否支持其它类型数据作为主键?
3.1在MongoDB中支持除了”数组类型以外的其它类型数据作为主键
3.2在MongoDB中甚至还支持将一个文档作为另一个文档的主键(复合主键)
05 MongoDB 可视化工具
mongodb manager pro
Navicat
06 MongoDB 创建文档
1.写入一个文档
document:需要写入的文档
writeConcern:写入安全级别
注意
insertOne一个不存在的集合,他会自动给创建
2.安全级别
用于判断数据是否写入成功,
安全级别越高,丢失数据风险越小,但是性能消耗(操作延迟)也就越大
默认情况下MongoDB会开启默认的安全些级别,先不用关心
3.注意点
在使用insertxxx写入文档时,如果调用insertOne的集合不存在会自动创建
4.其它方式
5.insertOne和save不同
主键冲突时insertOne会报错,而save会直接用新值覆盖久值
07 MongoDB 写入多个文档
1.写入多个文档
ordered:是否按顺序写入
ordered默认取值是true,也就是会严格按照顺序写入
如果ordered是false,则不会按照顺序写入,但写入效率更高(系统会自动优化)
2.注意点:
如果ordered是true,前面的文档出错,后面的所有文档都不会被写入
如果ordered是false,前面的文档出错,后面的所有文档也会被写入,出错的就不会被写入
3.写入一个或多个文档
3.1 insert是insertOne和insertMany结合体
3.2注意点:
- 和insertOne/insertMany一样,集合不存在会自动创建
- 和insertOne/insertMany一样,主键冲突会报错
08 查询文档和文档投影
1.查询文档
query:查询条件,相当于MySQL中的where
projection:投影文档,规定了结果集中显示那些字段,相当于MySQL中的
2.查询文档
3.查询满足条件文档
3.1单个字段条件
3.2多个字段条件
3.3文档中又是文档情况
4.投影文档
- 0就是需要隐藏的
- 1 需要显示的(默认都是1)
如果想查询某一个字段, 那么就可以指定这个字段的投影取值为1
默认情况下如果不指定, 帮么所有字段的投影取值都是1
除了_id字段以外,其它的字段不能同时出现O和 1
09 比较操作符
- 比较操作符
和MySQL一样,MongodDB中也支持很多比较操作符
2.使用格式
3.示例
查询名称叫做zs的人
查询所有成年人
查询所有未成年人
10 其他比较操作符
1.其它比较操作符
$in:匹配和任意指定值相等的文档
$nin:匹配和任意指定值都不相等的文档
2.使用格式
3.实例
查询名称叫做zs或者ls的人
查询名称不叫zs或者ls的人
查询性别不是男或女的人
注意点:和$eq一样没有指定字段也算作不包含
11 逻辑操作符
1.逻辑操作符
$not:匹配条件不成立的文档
$and:匹配条件全部成立的文档
$or 匹配至少一个条件成立的文档
$nor:匹配多个条件全部不成立的文档
2.示例:
2.1$not
查询所有年龄不等于18岁的人
查询不是男人的人
2.2 $and
查询所有名称叫做zs的未成年人
2.3 $or
查询所有名称叫做zs或者ls的人
2.4 $nor
查询所有名称不叫ls或者 zs的人
注意点:$nor上算符和 $ne/ $nin/$not一样,如果需要查询的字段不存在, 也会算作条件成立
查询所有名称不叫 ZS或者性别不是男的人
12 字段操作符
1.字段操作符
$exists: 查询包含某个字段的文档
$type: 查询指定字段包含指定类型的文档
2.查询包含字段gender的人
找出包含gender属性的人
不是男人的人(gender存在+不是男的)
3.应用场景:
配合 $ne/$not/$nor清理无用数据
查询出gender属性是字符串的类型
13 数组操作符
1.数组操作符
$all 匹配数组中包含所有指定查询值的文档
$elemMatch: 匹配数组中至少有一个能完全匹配所有的查询条件的文档
2.示例
查询tags中同时拥有html和 js的文档
查询出名字有ww,年龄18的班级
14 运算操作符
1.运算操作符
查询满足正则的文档
- 示例
查询姓z的文档
查询出姓z或者l的文档
15 文档游标
1.文档游标
1.1为什么学习前端都要学习MongoDB?
因为MongoDB原生就支持JavaScript,也就是我们可以直接在MongoDB中混入JS代码
插入一百个文档
1.2什么是文档游标
我们执行find方法后,find方法其实是有返回值的,find方法会返回一个文档游标(相当于C语言指针)
find返回的是所有数据的第一条的数据的地址
1.3文档游标常用方法
hasNext():是否还有下一个文档
next(): 取出下一个文档
forEach():依次取出所有文档
1.4文档游标注意点
默认情况下通过文档游标遍历完所有文档后,系统会在10分钟后自动关闭当前游标。
如果不想自动关闭,我们可以通过noCursorTimeout函数来保持游标一直有效
如果想手动关闭游标,我们也可以通过close函数来手动关闭游标
16 分页函数
1.分页方法
2.示例
3.分页函数注意点
可以在find后面直接调用limit和skip
芒果支持链式调用,skip函数永远在limit函数之前执行
17 排序函数
1.排序函数
2.示例
3.注意点
默认情况下find方法之后返回100条
3.1 find方法默认只会取出100个文档
3.2 sort函数永远在分页(limit/skip)函数之前执行
18 统计函数
1.统计函数
2.统计函数注意点
在find函数不提供筛选条件时,count函数会从集合的元数据中取得结果
在单台电脑上是这个结果是准确的,
但是如果数据库为分布式结构(多台电脑)时,如果不给find函数提供筛选条件,那么count函数返回的结果并不一定准确
19 更新文档
1.更新文档
MongoDB中有三个常用的更新方法:save /update/findAndmodify
2. save方法
save用于往集合里添加一个新文档或者覆盖文档
当没有指定文档_id的时候就是新增
当指定了集合中己经存在的_ id的时候就是覆盖
3.update 方法
- update方法
<filter>:筛选条件
<update>:新的内容
<options>:额外配置
- upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
- multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
- writeConcern :可选,抛出异常的级别。
2.通过update覆盖满足条件数据
默认情况下如果<update>没有使用更新操作符,那么就会使用指定的内容覆盖符合条件的内容
3.示例:
- 注意点:
4.1如果更新文档的时候指定了_id,那么指定的_id必须和被更新的文档的_id一致
4.2如果有多篇满足条件的文档,默认情况下update只会更新第一个满足条件文档
如果想更新所有满足条件的文档,那么就必须指定第三个参数
4.3注意点:如果在使用 update方法的时候, 在第二个参数中指定了 id,那么就必须保证指定的 id和被更新的文档的 id的取值一致,否则就会报错
开发技巧:在企业开发中如果需要供用 update方法,那么就不要指定 id
4.4注意点:如果想更新所有有满足条件的文档,我们可以指定第三个参数的取值 multi:true
注意点:如果指定了multi:true,那么就必须在第二个修数中使用更新操作服
20 更新操作符$set
1. 更新操作符
默认情况下update会使用新文档覆盖旧文档
如果不想覆盖而是仅仅想更新其中的某些字段
那么我们就需要使用update的更新操作符
2.$set更新操作符
$set:更新或者新增字段,字段存在就是更新,字段不存在就是新增格式:
3.示例:
3.1基本更新
3.2更新文档字段
3.3更新数组字段
注意点:如果操作的字段存在, 那么就是更新,如果操作的字段不存在, 那么就是新增
注意点:如果操作的是数组字段, 如果操作豪引不存在,了那么也会自动新增
如果被操作的索引前面没有数据, 那么会自动用 null来填充
21 更新操作符$unset
1.$unset更新操作符
$unset:删除字段
2.示例:
后面的值,是任何值都是可以的
删除普通字段
删除内嵌文档字段
删除数组元素
3.注意点:
3.1删除数组元素并不会影响数组的长度,而是设置为Null
3.2如果删除的字段不存在,不会做任何操作
22 更新操作符$rename
1.$rename更新操作符
$rename:重命名字段
2.示例
重命名普通字段
重命名内嵌文档字段
文档字段,取值需要注意层级关系
- 注意点
3.1如果需要重命名的字段不存在,不会做任何操作
3.2如果新的名称在文档中己经存在,那么原有字段会被删除
3.3文档字段,取值需要注意层级关系
先调用了$unset删除了原有的字段,再$set修改
3.4 不能$rename更新操作符来操作数组
$rename技巧
可以将外层的字段转移到内层的字段中,可以将内层的字段,转移到外层
23 更新操作符$inc和$mul
1. $ine和$mul更新操作符
只能操作数值类型的字段
$inc:更新字段值(增加或者减少字段保存的值)
$mul:更新字段值(乘以或者除以字段保存的值)
注意点:如果操作的字段不存在, 那么会自动新增
如果是$inc那么不仅仅会新增,还会将操作的值赋值给新增的字段
如果是 $mul那么只会新增字段,不会将操作的值赋值给新增的字段, 他是用 O来填充
24 更新操作符$min和$max
1.$min和$max更新操作符
$min:比较保留更小字段值
$max:比较保留更大字段值
2.示例
3.注意点:
3.1如果操作的字段不存在,会自动新增,并将操作的值赋值给新增的字段
3.2$min和$max不仅仅能操作数值类型,他们可以操作任何可以比较大小的类型
3.3如果比较的数据类型不同,同样可以更新
MongoDB对BSON的数据类型有一个潜在的排序规则(从小到大)
- null
- number
- Symbol String
- Object
- Array
- BinData
- ObjectId
- Date
- TimeStamp
- Regular Expression
25 更新操作符$addToSet
1.$addToSet数组更新操作符
SaddToSet:向数组字段中添加元素
2.示例
3.注意点
3.0如果操作的字段不存在,会自动创建这个字段
3.1如果添加的元素己经存在,不会重复添加
3.2如果添加的元素是文档,那么必须一模一样才不会重复添加
3.3如果往数组字段中添加的是数组,那么也必须一模一样才会去重
3.4如果往往数组字段中添如的是数组,郡么默认情况下会将整个数组作为一个元素添加进去。如果不想诶一个整体添加送去,那么必须使用 $each来添加
26 更新操作符$push
1.$push数组更新操作符
$push: 向数组字段中添加元素(不去重)
27 更新操作符$pop
1.$pop数组更新操作符
$pop:从数组字段中删除元素!
2.示例
3.注意点
数组中的元素都被删除以后,仍然会保留空的数组
28 更新操作符$pull
1.$pull数组更新操作符
$pull:从数组字段中删除特定元素
2.示例
3.注意点
- 如果要删除的元素是一个数组,那么必须一模一样才能删除
- 如果要删除的元素是一个文档, 那么不用一模一样也可以删除
29 更新操作符$pullAll
1.$pul1A11数组更新操作符
$pullAll:从数组字段中批量删除特定元素
2.注意点
- 和$pull一样,如果删除的是数字字段中的数组元素,那么必须一模一样才能删除
- 和$pull不一样,如果删除的是数组字段中的文档元素,那么也必须一模一样才能刑除
30 更新操作符$和$[]
1.$和$0]数组更新操作符
$:更新数组中满足条件的特定元素格式:
$[]:更新数组中所有元素
31 删除文档
1.删除文档
<query>:删除筛选条件
<options>:删除额外配置
2.示例
2.1删除所有满足条件
和update方法不同,remove方法默认就会删除所有满足条件的数据
2.2删除第一个满足条件
2.3删除所有文档
32 聚合操作$project
1.什么是聚合操作?
聚合操作就是通过一个方法完成一系列的操作
在聚合操作中,每一个操作我们称之为一个阶段
聚合操作会将上一个阶段处理结果传给下一个阶段继续处理, 所有阶段都处理完毕会返回一个新的结果集给我们
2.聚合操作格式
3.聚合管道阶段
$project:对输入文档进行再次投影
作用:按照我们需要的格式生成结果集
聚合操作不会修改原有的文档,而是返回一个新的文档给我们
如果在 $project聚合操作中使用了原有文格中不存在的字段, 那么会自动使用 Nul1来填充
33 聚合操作$match
1.聚合管道阶段
$match:和find方法中的第一个参数一样,用于筛选符合条件的文档
34 聚合操作$limit和$skip
1.聚合管道阶段
$limit:和游标的limit方法一样,用于指定获取几个文档格式 {$limit:<number>}
$skip: 和游标的skip方法一样,用于指定跳过几个文档格式:{$skip:<number>}
在聚合操作中 $limit和 $ skip是不同的阶段,所以要写到不同的对象中
35 聚合操作$unwind
1.聚合管道阶段
$unwind:展开数组字段
还可以包含索引。我们可以通过 includeArrayIndex来获取展开之前在原有数组中的素引
如果原有文档中没有需要保作的数组字段/数组字段中没有元素/ null,那么在 $unwind阶段,会自动将这些数据过滤。除非使用preserveNullandEmptyArray字段
- 作者:Kitety
- 链接:https://www.kitety.com/article/study-mongodb
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章