前言
MongoDB是一种面向文档的数据库管理系统,用C++等语言撰写而成,以解决应用程序开发社区中的大量现实问题。MongoDB由MongoDB Inc.(当时是10gen团队)于2007年10月开发,2009年2月首度推出,现以服务器端公共许可(SSPL)分发。(维基百科)
MongoDB和其他数据库的区别
- 数据库用
database
表示
- 集合(也就是其他数据库的数据表
table
)用collection
表示
- 字段(也就是其他数据库的字段
column
)用field
表示
- MongoDB的命令区分大小写
- MongoDB的命令末尾不需要分号
数据类型
- MongoDB通过BSON(一种二进制的JSON)来存储数据
- BSON数据类型
- 可以在Shell中使用的数据类型
- 字符串
- 对象id
- 布尔值
- 数组
- 32位整数
- 64位整数
- 64位浮点数
null
undefined
//i
正则表达式
function(){}
函数
- 不可以在Shell中使用的数据类型
对数据库的操作
切换(创建/使用)数据库
- 无论是否存在指定数据库名的数据库,在执行
use
命令后都会进入到指定数据库名的数据库
- 如果数据库名已存在,就进入到一个已存在的数据库进行操作
- 如果数据库名不存在,在创建集合后会自动创建这个数据库,在没有创建集合之前仍然不会出现在所有数据库列表中
<database_name>
:数据库名
数据库的命名规则
- 不能是空字符串
- 不能包含空字符(
\0
)
- 不能包含空格(
)
- 不能包含特殊字符:
.
、\
、/
、$
- 必须全部是小写字母
- 最长为64字节
默认数据库
- admin:存放所有用户和权限
- local:在这个数据库中存储的数据在部署集群后不会被同步
- config:存放分片的信息
删除当前数据库
查看当前数据库
查看所有数据库
对集合的操作
创建集合
显式创建
<collection_name>
:集合名
1
| db.createCollection(<collection_name>)
|
隐式创建
<collection_name>
:集合名 <key>
:键 <value>
:值
1
| db.<collection_name>.insert({"<key>": "<value>"})
|
1
| db.<collection_name>.insert({"<key_1>": "<value_1>", "<key_2>": "<value_2>"})
|
删除集合
1
| db.<collection_name>.drop()
|
查看所有集合
对文档的操作
新增文档
新增单条文档
1
| db.<collection_name>.insert({字段名: 字段值})
|
通过变量新增文档
1 2
| 变量名 = {字段名: 字段值} db.<collection_name>.insert(变量名)
|
新增多条文档
1
| db.<collection_name>.insertMany([{字段名1: 字段值1}, {字段名2: 字段值2}])
|
删除文档
删除所有符合条件的文档
1
| db.<collection_name>.remove({查询条件字段名: "查询条件字段值"})
|
删除全部文档
1
| db.<collection_name>.remove({})
|
修改文档
- 修改操作的第一个参数是查询条件
- 修改操作的第二个参数是修改后的文档
- 修改操作的第三个参数是其他参数,没有其他参数时可以省略
修改单条符合条件的文档
- 当查询到多条文档符合条件时,默认情况下只修改第一次符合条件的文档
覆盖修改
1
| db.<collection_name>.update({查询条件字段名: "查询条件字段值"}, {需要被修改的字段名: "修改后的字段值"})
|
局部修改
1
| db.<collection_name>.update({查询条件字段名: "查询条件字段值"}, {$set: {需要被修改的字段名: "修改后的字段值"}})
|
1
| db.<collection_name>.update({查询条件字段名: "查询条件字段值"}, {$set: {需要被修改的字段名1: "修改后的字段值1"}, $set: {需要被修改的字段名2: "修改后的字段值2"}})
|
字段值自增
1
:自增步长
1
| db.<collection_name>.update({查询条件字段名: "查询条件字段值"}, {$inc: {需要被修改的字段名: NumberInt(1)}})
|
修改多条符合条件的文档
覆盖修改
1
| db.<collection_name>.update({查询条件字段名: "查询条件字段值"}, {需要被修改的字段名: "修改后的字段值"}, {multi: true})
|
局部修改
1
| db.<collection_name>.update({查询条件字段名: "查询条件字段值"}, {$set: {需要被修改的字段名: "修改后的字段值"}})
|
1
| db.<collection_name>.update({查询条件字段名: "查询条件字段值"}, {$set: {需要被修改的字段名1: "修改后的字段值1"}, $set: {需要被修改的字段名2: "修改后的字段值2"}})
|
查询文档
查询所有文档
1
| db.<collection_name>.find()
|
1
| db.<collection_name>.find({})
|
查询符合条件的文档
完全匹配
查询符合条件的文档的多条文档
1
| db.<collection_name>.find({查询条件字段名: "查询条件字段值"})
|
1
| db.<collection_name>.find({查询条件字段名1: "查询条件字段值1", 查询条件字段名2: "查询条件字段值2"})
|
查询符合条件的文档的单条文档
1
| db.<collection_name>.findOne({查询条件字段名: "查询条件字段值"})
|
1
| db.<collection_name>.findOne({查询条件字段名1: "查询条件字段值1", 查询条件字段名2: "查询条件字段值2"})
|
正则匹配
1
| db.<collection_name>.find({查询条件字段名: /正则表达式/})
|
比较运算符
<num>
:数值
$gt
:大于 $gte
:大于等于 $lt
:小于 $lte
:小于等于 $eq
:等于 $ne
:不等于
1 2 3 4 5 6 7 8
| db.<collection_name>.find({"查询条件字段名": {$gt: NumberInt(<num>)}}) db.<collection_name>.find({"查询条件字段名": {$gte: NumberInt(<num>)}}) db.<collection_name>.find({"查询条件字段名": {$lt: NumberInt(<num>)}}) db.<collection_name>.find({"查询条件字段名": {$lte: NumberInt(<num>)}}) db.<collection_name>.find({"查询条件字段名": {$eq: NumberInt(<num>)}}) db.<collection_name>.find({"查询条件字段名": {$ne: NumberInt(<num>)}}) db.<collection_name>.find({"查询条件字段名": {$lt: NumberInt(<num>),$gte: NumberInt(<num>)}}) db.<collection_name>.find({"查询条件字段名": {$gt: NumberInt(<num>),$lte: NumberInt(<num>)}})
|
成员运算符
$in
:包含 $nin
:不包含
1 2
| db.<collection_name>.find({"查询条件字段名": {$in: ["查询条件字段值1", "查询条件字段值2"]}}) db.<collection_name>.find({"查询条件字段名": {$nin: ["查询条件字段值1", "查询条件字段值2"]}})
|
逻辑运算符
$and
:并且 $or
:或者
1 2
| db.<collection_name>.find({$and: [{"查询条件字段名": "查询条件字段值"}]}) db.<collection_name>.find({or: [{"查询条件字段名": "查询条件字段值"}]})
|
查询结果的筛选条件
添加查询结果的筛选条件
1
| db.<collection_name>.find({}, {查询结果字段名: 1})
|
1
| db.<collection_name>.find({}, {查询结果字段名1: 1, 查询结果字段名2: 1})
|
排除查询结果的筛选条件
1
| db.<collection_name>.find({}, {查询结果字段名: 0})
|
1
| db.<collection_name>.find({}, {查询结果字段名1: 0, 查询结果字段名2: 0})
|
混合条件
1
| db.<collection_name>.find({}, {查询结果字段名1: 1, 查询结果字段名2: 0})
|
查询文档总数
查询所有文档总数
1
| db.<collection_name>.count()
|
1
| db.<collection_name>.count({})
|
查询符合条件的文档总数
1
| db.<collection_name>.count({查询条件字段名: "查询条件字段值"})
|
查询指定数量的文档
1
| db.<collection_name>.find().limit(1)
|
跳过指定数量的文档
1
| db.<collection_name>.find().skip(1)
|
分页查询
1
| db.<collection_name>.find().skip((页数-1)*页内数据总数).limit(页内数据总数)
|
排序查询结果
升序
1
| db.<collection_name>.find().sort({需要排序的字段名: 1})
|
1
| db.<collection_name>.find().sort({需要排序的字段名1: 1, 需要排序的字段名2: 1})
|
降序
1
| db.<collection_name>.find().sort({需要排序的字段名: -1})
|
1
| db.<collection_name>.find().sort({需要排序的字段名1: -1, 需要排序的字段名2: -1})
|
混合排序
1
| db.<collection_name>.find().sort({需要排序的字段名1: 1, 需要排序的字段名2: -1})
|
查询结果转换为JSON
1
| db.<collection_name>.find().pretty()
|
高级查询
分组查询(GroupBy)
将输入表的字段名
的字段去重,得到新的一组数据,数据的字段名被定义为输出表中的字段名
1
| db.<collection_name>.aggregate({"$group": {"_id": {"输出表中的字段名": "$输入表的字段名"}}})
|
如果是嵌套的字段作为输入表的字段名
1
| db.<collection_name>.aggregate({"$group": {"_id": {"输出表中的字段名": "$输入表的字段名.输入表的子字段名"}}})
|
将输入表的字段名1
与输入表的字段名2
作为联合唯一键,得到新的一组数据
1
| db.<collection_name>.aggregate({"$group": {"_id": {"输出表中的字段名1": "$输入表的字段名1", "输出表中的字段名2": "$输入表的字段名2"}}})
|
捕获异常
- mongodb在执行批量操作时不会因为单条数据的操作失败而回滚,只能通过捕获异常来判断是否有执行失败的操作
1 2 3 4 5
| try { db.<collection_name>.insert({...}) } catch (e) { print(e) }
|
对索引的操作
- 通过已经创建了索引的字段进行查询时,效率会更高
- 如果查询的结果字段只有已经创建了索引的字段,那么MongoDB就直接从索引中获取数据,而不会再从集合中获取数据
查询索引
1
| db.<collection_name>.getIndexes()
|
新增索引
- 在当前数据库的指定集合上创建索引
- 每个集合中的
_id
字段默认就有升序索引,这个索引既不需要手动创建,也不会被删除
单字段索引
1
:升序索引 -1
:降序索引
1
| db.<collection_name>.createIndex({需要创建索引的字段名: 1})
|
升序索引名默认为被创建索引的字段名_1
1
| db.<collection_name>.createIndex({需要创建索引的字段名: -1})
|
降序索引名默认为被创建索引的字段名_-1
多字段索引(复合索引)
1
| db.<collection_name>.createIndex({需要创建索引的字段名1: 1, 需要创建索引的字段名2: -1})
|
索引名默认为被创建索引的字段名1_1_被创建索引的字段名2_-1
删除索引
删除单个索引
通过索引名删除索引
1
| db.<collection_name>.dropIndex(索引名)
|
通过规则删除索引
1
| db.<collection_name>.dropIndex({需要删除索引的字段名: -1})
|
删除所有索引
1
| db.<collection_name>.dropIndexes()
|
查询性能
1
| db.<collection_name>.find().explain()
|
queryPlainner.winningPlain.stage
> COLLSCAN
:全局扫描,没有使用索引 > FETCH
:抓取,使用索引扫描
用户
- 不同的角色有不同的权限
- 在创建用户时,通过为用户赋予角色,而控制用户权限
read |
可以读取指定数据库中的任何数据 |
readWrite |
可以读写指定数据库中的任何数据 |
readAnyDatabase |
可以读取所有数据库中的任何数据 |
readWriteAnyDatabase |
可以读写所有数据库中的任何数据 |
userAdmin |
可以在指定数据库创建和修改用户 |
userAdminAnyDatabase |
可以在任何数据库创建和修改用户 |
dbAdmin |
可以读取指定数据库,以及对数据库进行清理、压缩、获取统计信息、执行检查等操作 |
dbAdminAnyDatabase |
可以读取所有数据库,以及对数据库进行清理、压缩、获取统计信息、执行检查等操作 |
clusterAdmin |
可以对整个集群进行管理操作 |
restore |
可以还原数据库的数据 |
backup |
可以备份和还原数据库的数据 |
root |
拥有所有权限 |
新增用户
1 2
| use admin db.createUser({user:"用户名",pwd:"密码",roles:["角色名1", "角色名2"]})
|
创建超级管理员
1 2
| use admin db.createUser({user:"用户名",pwd:"密码",roles:["root"]})
|
创建普通管理员
1 2
| use admin db.createUser({user: "用户名", pwd: "密码", roles: {role: "userAdminAnyDatabase",db: "admin"}})
|
创建普通用户
1 2
| use 用户可以操作的数据库 db.createUser({user: "用户名", pwd: "密码", roles: {role: "readWrite", db: "用户可以操作的数据库"}})
|
删除用户
修改用户
修改用户密码
1
| db.changeUserPassword("用户名", "新密码")
|
查看用户
查看所有用户
登录
验证成功返回1
验证失败返回0
,提示:Error: Authentication failed
开启MongoDB的认证
完成
参考文献
程序媛 掘金——古拉里 掘金——六个周 CSDN——kalrry 哔哩哔哩——图灵学院教程 哔哩哔哩——黑马程序员 CSDN——lff0305