本篇学习笔记在学习 MongoDB 中文网内容时记录:https://mongodb.net.cn/manual/
一、MongoDB 学习笔记
1、基础概念
1)、文档数据库
MongoDB中的记录是一个文档,它是由字段和值对组成的数据结构。
MongoDB文档类似于JSON对象。字段的值可以包括其他文档,数组和文档数组。
使用文档的优点:
- json格式的文档适配大多数编程语言
- 嵌入式文档和数组减少了对昂贵连接的需求
- 动态模式支持流畅的多态性
MongoDB中的文档相当于传统关系数据库的一行记录。
2)、集合
Mongo将文档存储在集合(collection
)中,Mongo中的集合相当于传统关系型数据库的表。
3)、高性能
Mongo支持高性能的数据持久化:
- 减少数据库系统的I/O操作
- 支持索引,查询更快
4)、高可用
Mongo提供复制工具–副本集,功能包括:
- 自动故障转移
- 数据冗余
5)、可扩展
分片将数据分布在集群机器上
6)、支持多种存储引擎
WiredTiger、内存 存储引擎
2、基本操作(shell)
1)、数据库基本操作
显示当前使用数据库
db
test表示当前正在使用名为test的数据库,这也是登陆后默认使用数据库。
切换数据库
use learn1
如果不存在切换的数据库,mongo会在插入第一条记录时自动为我们创建该数据库。
可以通过db
语句验证当前所使用的数据库。
查看所有数据库
show dbs
2)、集合基本操作
查看所有集合
show collections
显示创建集合
db.createCollection(name, option)
Name表示集合名称
option是一个json文档,用来指定创建集合的配置
如果使用默认配置创建集合,则无需使用该方法。mongo在插入数据时会自动创建不存在的集合。
3)、插入基本操作
插入单个文档
db.myc.insertOne({name: 'kiki', age: 20})
使用该方法插入文档会展示插入结果以及插入文档的_id
字段。
如果在插入时未指定_id
字段,则mongo会自动创建一个ObjectId()数据作为_id
字段。
插入多个文档
db.myc.insertMany([
{name: 'lala', age: 20},
{name: 'nana', age: 21},
{name: 'haha', age: 23}
])
插入单个或者多个文档
db.myc.insert(documents, {writeConcern: {}, ordered: boolean})
documents表示单个文档或者文档数组
WriteConcern:
ordered:如果插入文档数组,是否按照顺序插入
原子操作
mongo中所有写操作都是单个文档级别的原子操作。
4)、查询基本操作
查询所有文档
db.myc.find({})
// 等同于 SELECT * FROM myc;
可以通过pretty()
方法美化输出格式。其他查询方法都可以通过该方法进行美化。
db.myc.find({}).pretty()
条件查询:平等条件
db.myc.find({name: 'nana'})
// 等同于 SELECT * FROM myc WHERE name='nana';
可以通过一个文档数据去指定查询条件。如图表示查询的文档数据必须包含 name=‘nana’ 这个字段
条件查询:查询运算符
db.myc.find({age: {$in: [21, 23]}})
// 等同于:SELECT * FROM myc WHERE age IN (21, 23);
图示为查询 age 属性在列表 [21, 23] 中的所有文档。
db.myc.find({age: {$gt: 21}})
// 等同于:SELECT * FROM myc WHERE age > 21;
图示为查询 age 属性大于 21 的所有文档
条件查询:and查询
db.myc.find({name: 'nana', age: {$lt: 23}})
// 等同于:SELECT * FROM myc WHERE name='nana' and age<23;
条件查询:or查询
db.myc.find({$or: [{name: 'nana'}, {age: {$gt: 21}}]})
// 等同于:SELECT * FROM myc WHERE name='nana' or age>21;
5)、更新基本操作
更新方法使用如下的方法签名:
update(<filter>, <update>, <options>)
- filter:用来过滤需要更新的字段
- update:更新的内容
- options:可选字段
更新单个文档
db.myc.updateOne(
{name: 'nana'},
{
$set: {name: 'nanaUpdate', age: 25},
$currentDate: {lastModified: true}
}
)
- 第一个文档用来过滤更新的文档,更新名称为nana的文档
- 第二个文档用来指定更新的内容
$set
运算符用来指定更新的内容$currentDate
将lastModified
字段更新为当前时间,如果lastModified
字段不存在,则创建。
更新多个文档
db.myc.updateOne(
{age: {$gt: 20}},
{
$set: {age: 19},
$currentDate: {lastModified: true}
}
)
该语句表示更新所有age>20的文档,并将文档的age字段设置为19。
更新单个文档的全部内容(替换文档)
db.myc.replaceOne(
{name: 'nanaUpdate'},
{name: 'nana', age: 20}
)
使用替换文档需要注意的:
- 替换文档需要将一个全新的文档作为第二个参数传递进
replaceOne()
方法中 - 替换文档时不包含更新操作符
- 替换文档时
_id
字段固定不变。如果想要加上,则必须与替换文档的_id
字段保持一致
6)、删除基本操作
删除所有文档
db.myc.deleteMany({})
直接传递一个空文档即可删除全部
删除多个文档:条件删除
db.myc.deleteMany({name: 'nana'})
传入一个文档指定查询条件,查询条件文档与查询基本操作一致
删除单个文档:条件删除
db.myc.deleteOne({name: 'nana'})
删除符合条件的第一个文档
3、其他CRUD操作
1)、批量操作(bulk operation)
批量写、更新、删除文档:builkWrite()
try {
db.characters.bulkWrite(
[
{ insertOne :
{
"document" :
{
"_id" : 4, "char" : "Dithras", "class" : "barbarian", "lvl" : 4
}
}
},
{ insertOne :
{
"document" :
{
"_id" : 5, "char" : "Taeln", "class" : "fighter", "lvl" : 3
}
}
},
{ updateOne :
{
"filter" : { "char" : "Eldon" },
"update" : { $set : { "status" : "Critical Injury" } }
}
},
{ deleteOne :
{ "filter" : { "char" : "Brisbane"} }
},
{ replaceOne :
{
"filter" : { "char" : "Meldane" },
"replacement" : { "char" : "Tanys", "class" : "oracle", "lvl" : 4 }
}
}
]
);
}
catch (e) {
print(e);
}
bulkWrite
内部支持操作有:insertOne
、updateOne
、updateMany
、replaceOne
、deleteOne
、deleteMany
。上面的每个操作都将以数组中的文档形式传给builkWrite
builkWrite
方法可以是有序的,也可以是无序的:
- 有序情况话会串行执行每个命令,写入效率低。串行执行过程中某个写入失败,后面的语句都将不会执行。
- 无序情况会并行执行每个命令,写入效率高。并行执行过程中某个写入失败,其他语句正常执行。
builkWrite
默认情况下是有序的,可以指定ordered: false
使其变为无序。
2)、可重试写入
可重试写入允许mongo在遇到网络错误或者其他未知影响情况下主动重写的操作
可重试写入条件:需要复制集或分片集群;需要特定的存储引擎支持(WiredTiger或内存引擎)
mongo4.2以上默认开始可重试写入,开启和关闭可以在连接mongo时通过以下语句:
mongo --retryWrites=true/false
mongo中的可重试写入只支持一次重试
3)、可重试读取
可重试读取与写入类似,开启语句如下:
mongo --retryReads=true/false