什么是 MongoDB
MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的数据库
这两种开源数据库的主要差别在于,MySQL 是关系型的,MongoDB 是基于文件存储的。
一.环境搭建和基础命令
1.拉取镜像
docker pull mongo:4.4.8
2.创建和启动容器
docker run -d --restart=always -p 27017:27017 --name mongo -v /mongo/data/db:/data/db mongo:4.4.8 --auth
docker run : 表示创建一个新的容器
-d :表示后台运行
--restart=always : 表示docker启动,当前的容器也跟着启动
-p 27017:27017 :表示端口映射
--name atguigu_syt_mongo :表示给当前的容器取一个名字
-v /atguigu/syt/mongo/data/db:/data/db mongo:4.4.8 :表示目录挂载
--auth :表示权限,权限可加可不加,如果添加了权限,那么后面连接服务器就需要设置用户名和密码
3.进入容器
docker exec -it mongo /bin/bash
4.进入MongoDB客户端
mongo
5.创建超级用户
show dbs #查看数据
use admin #切换表(必须切换到admin表,才能添加用户)
db.createUser({ user: "root" , pwd: "123456", roles: ["root"]})
6.登录mongoDB
# 返回值是1,表示成功
# 只能切换到admin数据库,才可以登录root用户
db.auth("root","123456")
基本命令
db.version() #当前db版本
db.getMongo() #查看当前db的链接机器地址
db.help() #帮助
quit() #退出命令行
二.数据库操作
# 查看默认有哪些数据库
show databases
或者
show dbs
# 退出数据库
exit
# 连接数据库
mongo
# 查看参数
mongo --help
# 创建数据库,如果有数据直接进入,如果没有数据库,创建完成之后,在进去
# 如果创建好数据库,里面没有数据,不会显示,必须插入一条数据,才会显示
use abc
# 清理屏幕
cls
# 查看我在哪个数据库
db
# 删除数据库
db.dropDatabase()
# 在新建数据库的时候,取名字
① 不能使用空字符串
② 不能含有特殊字符 ,比如空格,$ , \
③ 数据库的名字必须小写
④ 最多只有64个字节
# 默认情况下,系统有三个数据库
admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。
local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
三.操作表(文档)
mongo里面没有表的概念,所有的表,叫做文档
# 创建文档(创建表)
db.createCollection("名字")
# 查看刚刚创建的表
show collections
或者
show tables
# 删除表
db.名字.drop()
# 创建文档的名字需要注意,不能使用特殊字符,不能使用空格,不能使用system这样的关键字
四.插入数据
# 插入单条数据
# 插入数据 注意如果没有文档,系统会帮助我们自动创建文档
db.文档的名字.insert({
写的是json数据
})
# 批量插入数据
db.文档的名字.insertMany({
[插入多条json数据]
})
插入多条数据,下面的CRUD基于此数据
db.comment.insertMany(
[{
"_id":"1",
"articleid":"100001",
"content":"我们不应该把清晨浪费在手机上,健康很重要。",
"userid":"1002","nickname":"相忘于江湖",
"createdatetime":new Date("2019-08-05T22:08:15.522Z"),
"likenum":NumberInt(1000),
"state":"1"
},
{
"_id":"2",
"articleid":"100001",
"content":"我夏天空腹喝凉开水,冬天喝温开水",
"userid":"1005",
"nickname":"伊人憔悴",
"createdatetime":new Date("2019-08-05T23:58:51.485Z"),
"likenum":NumberInt(888),
"state":"1"
},
{
"_id":"3",
"articleid":"100001",
"content":"我一直喝凉开水,冬天夏天都喝。",
"userid":"1004",
"nickname":"杰克船长",
"createdatetime":new Date("2019-08-06T01:05:06.321Z"),
"likenum":NumberInt(666),
"state":"1"
},
{
"_id":"4",
"articleid":"100001",
"content":"专家说不能空腹吃饭,影响健康。",
"userid":"1003",
"nickname":"熊大",
"createdatetime":new Date("2019-08-06T08:18:35.288Z"),
"likenum":NumberInt(2000),
"state":"1"
},
{
"_id":"5",
"articleid":"100001",
"content":"研究表明,刚烧开的水千万不能喝,因为烫嘴。",
"userid":"1003",
"nickname":"熊大",
"createdatetime":new Date("2019-08-06T11:01:02.521Z"),
"likenum":NumberInt(3000),
"state":"1"
}]);
五.查询数据
# 查询所有返回所有的字段
db.文档名字.find()
# 根据条件进行查询
db.文档的名字.find({字段:"value"})
# 查询单条语句
db.文档的名字.findOne({字段:"value"})
# 投影查询(查询部分字段)
db.文档的名字.findOne({字段:"value"},{字段:1})
六.更新数据
默认情况下,是全局更新
如果我们想修改_id为1的记录,点赞量为1001,输入以下语句:
db.comment.update({_id:"1"},{likenum:NumberInt(1001)})
局部更新
db.comment.update({_id:"2"},{$set:{likenum:NumberInt(889)}})
批量更新
更新所有用户为 1003 的用户的昵称为张三 。
# 只会更新第一条
db.comment.update({userid:"1003"},{$set:{nickname:"张三"}})
# 更新所有符合条件
db.comment.update({userid:"1003"},{$set:{nickname:"张三"}},{multi:true}) #multi:true表示批量更新
如果我们想实现对某列值在原有值的基础上进行增加或减少,可以使用 $inc 运算符来实现。
需求:对3号数据的点赞数,每次递增1
自增+1
db.comment.update({_id:"3"},{$inc:{likenum:NumberInt(1)}})
七.删除数据
# 删除id为1的数据
db.comment.remove({_id:"1"})
# 删除所有
db.comment.remove({})
八.统计查询
# 统计所有
db.comment.count()
# 根据条件进行统计
db.comment.count({userid:"1003"})
九.分页查询
# 查询第一页数据
db.comment.find().skip(0).limit(2)
# 查询第二页数据
db.comment.find().skip(2).limit(2)
# 查询第三页数据
db.comment.find().skip(4).limit(2)
十.排序查询
sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。
db.comment.find().sort({userid:1})
常用命令总结:
选择切换数据库:use articledb
插入数据:db.comment.insert({bson数据})
查询所有数据:db.comment.find();
条件查询数据:db.comment.find({条件})
查询符合条件的第一条记录:db.comment.findOne({条件})
查询符合条件的前几条记录:db.comment.find({条件}).limit(条数)
查询符合条件的跳过的记录:db.comment.find({条件}).skip(条数)
修改数据:db.comment.update({条件},{修改后的数据}) 或db.comment.update({条件},{$set:{要修改部分的字段:数据})
修改数据并自增某字段值:db.comment.update({条件},{$inc:{自增的字段:步进值}})
删除数据:db.comment.remove({条件})
统计查询:db.comment.count({条件})
模糊查询:db.comment.find({字段名:/正则表达式/})
条件比较运算:db.comment.find({字段名:{$gt:值}})
包含查询:db.comment.find({字段名:{$in:[值1,值2]}})或db.comment.find({字段名:{$nin:[值1,值2]}})
条件连接查询:db.comment.find({$and:[{条件1},{条件2}]})或db.comment.find({$or:[{条件1},{条件2}]})
索引:
索引支持在MongoDB中高效地执行查询。如果没有索引,MongoDB必须执行全集合扫描,即扫描集合中的每个文档,以选择与查询语句
匹配的文档。这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非 常致命的。
# 查询索引
db.comment.getIndexes()
# 创建索引
db.comment.createIndex({userid:1})
# 移除索引
db.collection.dropIndex(index)
例子:
在 MongoDB 中,可以使用 createIndex() 方法手动创建索引,该方法通常需要指定要创建索引的集合和要创建索引的字段。例如,假设有一个名为 users 的集合,其中包含 name 和 age 两个字段,我们可以分别创建这两个字段的索引,如下所示:
// 创建 name 字段的索引
db.users.createIndex({name: 1})
// 创建 age 字段的索引
db.users.createIndex({age: 1})
在上述示例中,createIndex() 方法接受一个对象作为参数,该对象的键表示要创建索引的字段,值表示要创建索引的方向,其中 1 表示升序,-1 表示降序。例如,{name: 1} 表示创建 name 字段的升序索引。
除了单个字段的索引外,还可以创建复合索引,这种索引可以包含多个字段,例如:
// 创建 name 和 age 字段的复合索引
db.users.createIndex({name: 1, age: -1})
在上述示例中,{name: 1, age: -1} 表示创建一个以 name 字段为升序,age 字段为降序的复合索引。
需要注意的是,索引的创建可能会影响数据库的性能和存储空间,因此需要根据实际情况进行权衡和选择。同时,还可以使用 getIndexes() 方法查看集合中已经创建的索引,以确保索引的正确性和完整性。