MongoDB基础
# NoSQL类型数据库
以MySQL为代表的关系型数据库采用表格的形式组织数据。表格有行和列,要求数据项拥有固定的属性。而MongoDB则是NoSQL类型的数据,采用 文档(Document) 和 集合(Collection) 的方式组织数据,文档可以类比于SQL中的一个数据项,集合则类比于SQL中的表格。文档和数据项最大的区别在于文档中的属性更加自由,不需要像SQL一样需要遵守表格定义的列。
# 安装
前往安装MongoDB (opens new window)和安装Mongosh (opens new window),按照提示安装完成后,打开命令行工具,输入
mongosh
如果看见MongoDB和Mongosh的版本号则说明连接成功。
# 基础命令
成功连接到MongoDB会,会默认连接到一个名为test的数据库。在正式对数据库进行操作之前,首先记住一些常见命令:
命令 | 作用 |
---|---|
mongosh | 连接到MongoDB实例,所有操作都是在这个命令生效之后的 |
show dbs | 展示当前实例中所有的数据库 |
use databaseName | 使用指定名称的数据库,如果数据库不存在时会自动创建 |
db | 展示当前数据库的名字 |
show collections | 展示当前数据库中的所有集合 |
db.DropDatabase() | 删除当前数据库 |
exit | 关闭和当前实例的连接 |
# 创建数据
假设我们希望在appdb这个数据库的user集合中创建新的数据,可以顺序数据以下命令
use appdb
db.user.insertOne({name: 'Kyle'})
如果希望一次性创建多个数据,可以使用insertMany
db.user.insertMany([{name: 'Jack', age: 20}, {name: 'Rose', age: 24, hobbies: ['Running']}])
可以发现的一个特点是,创建的数据所拥有的属性是非常自由的,设置还可以存在嵌套,这正是MongoDB最大的特点之一。
# 读取数据
# 展示一个集合中的所有数据
find
用于将一个集合中的所有数据进行展示
db.user.find()
如果只需要一个文档,也可以使用findOne
。
# 按条件筛选
一般情况下并不会直接展示所有数据,而是按照某些条件对数据进行筛选。在SQL中是WHERE来实现,而在MongoDB中则可以直接通过将筛选条件作为参数传递给find
来实现。
db.user.find({ name: 'Kyle' })
这一段命令的意思是找到user集合中name属性为Kyle的所有文档。一般以find(<filterObject>)
的形式来编写。
SQL中还有一种比较方便的读取数据形式,可以通过SELECT来指定筛选出的数据的特点属性。比如如果只需要筛选出的所有文档的年龄,则可以采用find(<filterObject>, <selectObject>)
的方式进行编写
db.user.find({ name: 'Kyle' }, { age: 1 })
db.user.find({}, { age: 0 })
第一行表示找到所有name为Kyle的文档并且只保留age属性(id一般情况还是会默认返回)。第二行的意思是读取所有文档,但是去除所有文档的age属性。不难发现,在selectObject
中通过属性值的0和1就可以实现SELECT一样读取指定列数据的功能。
# 计数
类似COUNT
聚合函数一样,MongoDB也可以实现对满足条件的文档进行计数:
db.user.countDocuments({ name: 'Kyle' })
# 更新数据
和SQL中一样,更新数据也是先找到需要更新数据的文档,然后指定需要更新的属性以及新的属性值。MongoDB中主要使用updateOne
和updateMany
来实现:
db.user.updateOne({ age: 20 }, { $set: { age: 21 } })
db.user.update({ age: 18 }, { $inc: { age: 3 } })
第一个参数是筛选条件,第二个参数则是更新方法。$set
和$inc
这样的称为复杂更新对象方法,后面会详细介绍。
更新数据还有类似relaceOne
这样直接替代原有项的办法,但是不推荐使用
# 删除数据
删除数据使用deleteOne
和deleteMany
,使用方法和前面类似。输入筛选条件后进行删除即可。
# 复杂更新对象
MongoDB内置的一些方法,可以实现更加复杂的数据更新操作。
更新对象 | 例子 | 作用 |
---|---|---|
$set | db.users.updateOne({ age: 12 }, { $set: { name: “Hi” } }) | 指定需要更新的属性以及新的属性值 |
$inc | db.users.updateOne({ age: 12 }, { $inc: { age: 2 } }) | 在原有数据的基础上增加的值 |
$rename | db.users.updateMany({}, {$rename: { age: “years” } }) | 更改某一个属性的属性名 |
$unset | db.users.updateOne({ age: 12 }, { $unset: { age: “” } }) | 移除指定的属性 |
$pull | db.users.updateMany({}, { $pull: { friends: “Mike” } }) | 删除属性值为数组的属性中的某一个值 |
$push | db.users.updateMany({}, { $push: { friends: “John” } }) | 向属性值为数组的属性中添加新数据 |
# 复杂筛选对象
上面提到的一些简单的筛选方法还不足以满足基本的使用需求,搭配下表所列的一些复杂筛选对象,能够实现更多的操作。
筛选对象 | 例子 | 作用 |
---|---|---|
$eq | db.users.find({ name: { $eq: 'Kyle' } }) | 筛选具有对应属性值的文档 |
$ne | db.users.find({ name: { $ne: 'Kyle' } }) | 筛选不具有对应属性值的文档 |
$gt/$gte | db.users.find({ age: { $gt: 15 } }) | 筛选对应属性值大于/大于等于指定值的文档 |
$lt/lte | db.users.find({ age: { $lt: 30 }}) | 筛选对应属性值小于/小于等于指定值的文档 |
$in | db.users.find({ name: { $in: ['Kyle', 'Mike'] } }) | 筛选属性值被包含在指定数组中的文档 |
$nin | db.users.find({ name: { $nin: ['Kyle', 'Mike'] } }) | 筛选属性值被不包含在指定数组中的文档 |
$and | db.users.find({ $and: [{ age: 12 }, { name: “Kyle” }] }) | 筛选同时符合多个条件的文档 |
$or | db.users.find({ $or: [{ age: 12 }, { name: “Kyle” }] }) | 筛选符合多个条件中一个的所有文档 |
$not | db.users.find({ name: { $not: { $eq: “Kyle” } } }) | 筛选不符合给定条件的文档 |
$exists | db.users.find({ name: { $exists: true } }) | 筛选存在某一个特定属性的文档 |
$expr | db.users.find({ $expr: { $gt: [“$balance”, “$debt”] } }) | 对同一文档的属性作比较并设定筛选条件 |
# 小结
本文所写的内容参考视频Learn MongoDB in 30 minutes (opens new window),对于不了解后端知识的前端开发者而言可以作为一个快速入门教程,但还是建议先看看SQL相关的知识。关于MongoDB指令的快速查找清单可以参考MongoDB Cheat Sheet (opens new window)。