目录
介绍
1. MongoDB是一款非关系型数据库(NoSQL),是一个基于文档的数据库,数据以类似JSON的BSON(Binary JSON 二进制形式的JSON)格式进行存储。但我们在操作数据时是以JSON格式进行交互的,因为内部存在JSON和BSON的转换。
2. MongoDB可以存储复杂的数据结构,包括嵌套JSON对象和数组等。
3. MongoDB主要以磁盘进行存储,但存在磁盘映射加快数据的访问,所以适合存储大量的数据。
4. 由于依赖磁盘存储,所以性能相对Redis来说稍低,但是通过内存映射和缓存机制仍然能处理高并发和大量数据的读写请求。
5. MongoDB支持像MYSQL那样的复杂查询,并且支持事务(ACID),索引等。
看看存储结构
如上是同一个集合/表中的所有文档(JSON)数据,可以看到存储的方式是很灵活,第三个文档数据多了个gender字段,第四个文档数据的结构跟前三个完全不同,这是因为MongoDB是不用事先定义好集合/表结构的。
但是这样的存储一般是不推荐的,一般把相同/相似的数据结构存放到同一集合中。
通过如上的存储方式,我们知道存储的数据就是一堆JSON格式的数据。
安装MongoDB
如下在CentOS8中使用Docker进行MongoDB的安装。
1. 拉取MongoDB镜像
docker pull mongo:latest
2. 创建本地文件夹映射数据卷
创建文件夹:config (配置) , data (数据) , logs(日志)
创建文件:mongod.conf(启动配置文件)
mkdir -p 你的目录(如/mongo,自定义)/config
mkdir -p 你的目录/data
mkdir -p 你的目录/logs
touch 你的主目录/config/mongod.conf
chmod 777 你的目录
3. 编辑配置文件(mongod.conf)
# 数据库存储路径
dbpath=你的目录/data
# 日志文件路径
logpath=你的目录/logs/mongod.log
# 监听的端口
port=27017
# 允许所有的 IP 地址连接
bind_ip=0.0.0.0
# 启用日志记录
journal=true
# 是否后台运行
fork=true
# 启用身份验证
#auth=true
4. 启动MongoDB容器
docker run -dit --name mongo \
-p 27017:27017 \
-v 你的目录/config/mongod.conf:/etc/mongod.conf \
-v 你的目录/data:/data/db \
-v 你的目录/logs:/var/log/mongodb \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=123456 \
--restart=always \
mongo
5. 测试链接,使用
# 进入MongoDB的命令行(Mongo shell)
docker exec -it mongo /bin/mongosh
# 切换到admin数据库进行身份验证
use admin
db.auth("admin", "123456")
# 查看所有数据库
show dbs
查看数据库状态-常用命令表
用户管理
创建管理员用户
db.createUser(
{
user:"user_1",
pwd:"123456",
roles:[{role:"root"}]
}
);
创建特定数据库管理员
如果我们想要创建某个数据库的管理员,让此用户仅仅能看到指定的数据库,而不能看到其他数据库,可以这样:
db.createUser(
{
user:"user1",
pwd:"123456",
roles:[{role:"dbOwner",db:"my_db"}]
}
);
删除用户
db.dropUser({'user1'})
查看所有用户
show users
数据库创建和删除
我们可以使用use命令来创建数据库,当use 的数据库不存在时,则是新增。
例如:我们要创建数据库my_db,可以使用:use my_db
创建新数据库:newDB,使用show dbs查看不直接显示newDB数据库
然后在newDB下新建一个集合tb1
再次show dbs查看,可以看到newDB正常显示。
删除数据库
db.dropDatabase("数据库名")
集合的创建和删除
查看数据库中的所有集合
show tables
or
show collections
创建
db.createCollection("集合名称")
删除
db.集合名.drop()
文档操作(CRUD)
新增操作
# 插入单条数据
db.my_c.insertOne({name: "张三", age: 18})
# 批量插入数据
db.my_c.insertMany([{name: "Tom1", age:90}, {name: "Jerry", age: 100}...])
通过js脚本批量插入数据
JS脚本的执行:
命令:load("JS脚本文件路径")
查询操作
查询所有
db.集合名.find()
简单条件查询
db.my_c.find({age: 18})
db.my_c.find({age: 18, name: "张三"})
复杂条件查询
查询年龄大于50的用户:
以及,逻辑对照表:
排序和分页
分页查询
例如每页显示10条,输出第三页:
db.my_c.find().skip(20).limit(10);
模糊查询
更新文档
db.my_c.update({name: "Jerry"}, {$inc:{age: 1}})
其中使用到了更新操作符“$inc”,更多更新操作符:
# 更新匹配到的所有数据
db.my_c.update({name: "Jerry"}, {$inc:{age: 1}}, {"multi": true})
删除文档
# 删除单个
db.my_c.deleteOne({age: 18})
# 删除所有匹配项
db.my_c.deleteMany({age: 18})
MongoDB可视化操作数据的软件
官方软件:MongoDBCompass
下载地址:MongoDB Compass Download (GUI) | MongoDB
Navcat也可以连接MongoDB
但是Navcat可提供的操作相对MongoCompass更局限一些。
聚合操作
单一聚合
提供简单的聚合操作,如单求平均值,求和等,都是在单个集合中进行操作。
如:统计个数,去重操作
可以看到.count()显示方法已经过时。
聚合管道
对于更复杂的聚合操作,一般使用聚合管道实现,聚合管道非常的灵活,可以任意组合聚合操作,将上一个聚合操作的输出数据,作为下一个聚合操作的输入数据。
聚合管道操作表
# 我们可以通过$match 和 $project配合使用,达到效果
db.my_c.aggregate([{$match: {age:{$gt:10}}}, {$project: {name: 1}}])
如上,我们先通过$match过滤出年龄大于10的所有用户信息,然后将数据传递到$project做投影操作,仅取出名称。
值得注意的是:一个重要的聚合操作$lookup
$lookup
我们可以通过lookup进行多表联合查询。
更多聚合操作或示例:聚合管道 - MongoDB手册
索引操作
MongoDB和MYSQL一样都存在索引,且两者的索引结构实现都是B+树,目的就是为了提高查询效率。
创建索引
可选参数表:
# 为name字段创建单独的索引
db.my_c.createIndex({name: 1})
# 创建name 和 age字段的复合索引
db.my_c.createIndex({name: 1, age: 1})
查看索引
db.集合名.getIndexes()
删除索引
# 删除集合中指定索引
db.集合名.dropIndex("索引名")
# 删除集合中所有索引
db.集合名.dropIndexes()
检查索引的使用
我们可以使用explain工具查询MongoDB的执行计划,查看查询是否使用了索引。
没有索引的情况:执行“db.my_c.find({age: {$gt:18}}).explain()”
可以看到为“COLLSCAN”,意思为全表扫描,时间复杂度为O(n)效率必然差些。
我们给age字段添加上索引,再次查询: