MongoDB
简介
- 非关系型、文档型数据库
- 是为快速开发互联网Web应用而设计的数据库系统
- 设计目标是极简、灵活,作为Web应用栈的一部分
- 数据模型是面向文档的。所谓文档就是一种类似于JSON的数据结构,简单理解MongoDB这个数据库中存的是各种各样的JSON
- MongoDB中的数据叫做BSON,是增强版的JSON,B即Binary,二进制,即MongoDB中可以存二进制的数据
相关概念
数据库(Database)
数据库即存储数据的仓库,数据库中可以存放集合
集合(Collection)
集合类似于数组,在集合中可以存放文档
文档(Document)
文档是数据库中的最小单位,我们存储和操作的内容都是文档
注:在MongoDB中,数据库和集合都不需要手动创建,当我们创建文档时,如果文档所在的集合和数据库不存在,会自动创建
基础指令
命令 | 含义 |
---|---|
show dbs或者show databases | 显示当前所有的数据库 |
use 数据库名 | 进入到指定数据库 |
db | 查看当前所处的是哪个数据库 |
show collections | 显示当前数据库中所有集 |
数据库的CRUD操作
插入数据
db.<collection>.insert(doc)
例:
向test数据库的stus集合中插入一个学生对象:{name:"小明", age: 18, gender: "男"}
需要执行的指令为:db.stus.insert({name:"小明", age: 18, gender: "男"})
其中db代表当前数据库
注:
-
插入文档时,如果没有指定_id属性,则数据库会自动为文档添加_id属性,该属性用来确保该文档的唯一性。(根据时间戳 + 机器码生成,基本不会重复)
-
自己指定_id属性时,也要确保该属性的唯一性。插入重复的_id会报错:_
E11000 duplicate key error collection: admin.stus index: _id_ dup key
db.<collection>.insertOne(doc)
插入一个文档,参数只能传一个文档,不能传数组
db.<collection>.insertMany(doc)
插入多个文档,参数只能传数组
查询数据
db.<collection>.find()
查询指定集合中所有文档
find()接收的参数是一个对象,不传或者传一个空对象(即{ })相当于查询所有
查询符合指定条件的:
/*
查询指定属性等于指定值得文档,多个属性之间是且的关系
*/
db.<collection>.find({属性1:值1, 属性2:值2...})
find()返回的是一个数组,所以可以在该方法基础上加索引,如:
/*
取查询结果的第0个元素
*/
db.<collection>.find({属性1:值1, 属性2:值2...})[0]
可以在find()后面加.count()或.length(),获取查询到的文档数量(一般用.count()),如:
/*
获取查询到的文档数量
*/
db.<collection>.find({属性1:值1, 属性2:值2...}).count( )
db.<collection>.findOne()
查询集合中符合条件的第一个文档
返回的是一个文档对象,所以可以在该方法的基础上.属性名来获取具体属性值,比如:
db.<collection>.findOne({属性1:值1, 属性2:值2...}).属性
修改数据
db.<collection>.update(查询条件, 修改后的对象)
默认情况下,update方法会使用参数中修改后的对象来替换查找到的对象,而不是修改对应属性的值,所以对象的属性会发生变化。
如:
/*
替换
*/
db.<collection>.update({name:"sxy"}, {age: 18})
该命令会把查询到的name为sxy的文档,替换为{age: 18}。name属性就丢失了。
如果想要仅修改指定数据,可以使用操作符
update()方法默认只会修改查询到的第一个文档,但也可以增加第三个参数,配置multi属性,以修改多个文档,如:
db.<collection>.update(
{name:"sxy"},
{age: 18},
{multi:true}
)
db.<collection>.updateMany(查询条件, 修改后的对象)
修改查询到的所有文档
db.<collection>.updateOne(查询条件, 修改后的对象)
修改查询到的第一个文档
db.<collection>.replaceOne(查询条件, 替换后的对象)
替换查询到的第一个文档
操作符
$set
/*
修改指定属性,下例中只会修改age属性,其他属性保持不变
*/
db.<collection>.update(
{name:"sxy"},
{
$set:{
age: 18
}
}
)
$unset
/*
删除指定属性,下例中只会删除age属性,其他属性保持不变
因为这里是删除,所以age后面的值可以随便写
*/
db.<collection>.update(
{name:"sxy"},
{$unset:{
age: 18
}
}
)
删除数据
删除文档
db.<collection>.remove(查询条件)
删除符合条件的所有文档 ,默认会删除多个
如果想只删除一个,则可以传递第二个参数为true,表示只删除一个
注:
remove()方法必须传参,可以传一个空对象,如果传一个空对象,则会删除该集合内的所有文档,也就是清空集合
但在清空集合时,一般不采用这种方法,因为这种方法是先匹配再删除,效率略低
清空集合可以直接删除集合,即:
db.<collection>.drop()
db.<collection>.deleteOne()
删除符合条件的一个文档
db.<collection>.deleteMany()
删除符合条件的所有文档
删除集合
/*
如果删除集合后,该集合所处的数据库没有集合了,则该数据库也会自动删除
*/
db.<collection>.drop()
删除数据库
db.dropDatabase()
文档间关系
MongoDB中,文档之间也拥有一对一、一对多、多对多的关系,与关系型数据库类似
排序
在使用find()时,默认是按照_id升序排列,又由于_id是根据时间戳和机器码生成的,所以find()默认是按照创建时间排序的,先创建的在前面
可以使用sort()方法来进行排序,如:
db.<collection>.find().sort({排序字段1:升序/降序, 排序字段2:升序/降序...})
其中,1表示升序,-1表示降序
投影
概念
查询指定字段
方式
db.<collection>.find({属性1:值1, 属性2:值2...}, {字段: 0/1})
其中,0为不显示该字段,1为显示该字段
扩展
Mongoose
简介
- 是一个可以让我们通过Node来操作MongoDB的模块
- 是一个对象文档模型(ODM)库,它对Node原生的MongoDB模块进行了进一步的优化和封装,并提供了更多的功能
- 在大多数情况下,它被用来把结构化的模式应用到MongoDB集合,并提供了验证和类型转换等好处
优势
- 可以为文档创建一个模式结构(Scheme)
- 即创建一个约束
- 由于MongoDB中存的数据没有任何约束,就会导致在存储数据时可以存入不符类型要求的数据,比如员工工资字段,存入了一个字符串类型。
- 可以对模型中的对象/文档进行验证
- 即是否符合约束
- 数据可以通过类型转换转换为对象模型
- 即对于可以类型转换的数据,可以进行自动的类型转换,将其转换为符合约束的数据
- 可以使用中间件来与业务逻辑挂钩
- 比Node原生的MongoDB驱动更容易
新的对象
Mongoose提供的新对象:
-
Scheme(模式对象)
Scheme对象约束了数据库中的文档结构。即文档中有哪些字段、字段是什么类型、哪些字段非空等
-
Model
Model对象作为集合中所有文档的表示,相当于MongoDB中的Collection
-
Document
Document表示集合中的具体文档,相当于集合中一个具体的文档
Q.E.D.