MongoDB学习笔记
MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数类型。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系据库单表查询的绝大部分功能,而且还支持对数据建立索引。
一 安装与卸载
在Red Hat或CentOS上安装MongoDB企业版-官网文档
以下为通过yum在CentOS安装MongoDB-5.0企业版
1.1 配置存储库
-
创建一个 /etc/yum.repos.d/mongodb-enterprise-5.0.repo文件
vim /etc/yum.repos.d/mongodb-enterprise-5.0.repo
-
在文件中写入以下内容
[mongodb-enterprise-5.0] name=MongoDB Enterprise Repository baseurl=https://repo.mongodb.com/yum/redhat/$releasever/mongodb-enterprise/5.0/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc
1.2 安装MongoDB Enterprise软件包
sudo yum install -y mongodb-enterprise
1.3 启动
systemctl start mongod
# 通过配置文件启动
/usr/bin/mongod -f /etc/mongod.conf
1.4 通过命令行窗口连接后简单使用
mongosh # 连接数据库
db # 查看当前数据库
show dbs # 显示所有数据库
use test # 使用test数据库,没有就创建
show collections # 显示所有集合
show tables # 显示所有表
db.inventory.insertMany([
{ item: "journal", qty: 25, status: "A", size: { h: 14, w: 21, uom: "cm" }, tags: [ "blank", "red" ] },
{ item: "notebook", qty: 50, status: "A", size: { h: 8.5, w: 11, uom: "in" }, tags: [ "red", "blank" ] },
{ item: "paper", qty: 10, status: "D", size: { h: 8.5, w: 11, uom: "in" }, tags: [ "red", "blank", "plain" ] },
{ item: "planner", qty: 0, status: "D", size: { h: 22.85, w: 30, uom: "cm" }, tags: [ "blank", "red" ] },
{ item: "postcard", qty: 45, status: "A", size: { h: 10, w: 15.25, uom: "cm" }, tags: [ "blue" ] }
]); # 插入多条数据
db.insertMany.find({}).pretty() #查询所有后格式化输出
db.inventory.find( { status: "D" } ).pretty(); # 查询 status = D
db.inventory.find( { qty: 0 } ).pretty(); # 查询 qty = 0
db.inventory.find( { qty: 0, status: "D" } ).pretty(); # 查询 qty = 0 并且 status = D
db.inventory.find( { "size.uom": "in" } ).pretty(); # 查询 size 里面 uom = in
db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } } ).pretty(); # 查询 size 中 h =14 并且 w = 21 并且 uom = cn
db.inventory.find( { tags: "red" } ).pretty(); # 查询 tags 中包含 red
db.inventory.find( { tags: [ "red", "blank" ] } ).pretty(); # 查询 tage 为 [ "red", "blank" ]
db.inventory.find( { }, { item: 1, status: 1 } ).pretty(); # 查询结果只返回 item 和 status,1表示要返回的,_id 默认返回
db.inventory.find( {}, { _id: 0, item: 1, status: 1 } ).pretty(); # 0表示不返回的
db.inventory.drop() # 删除user表
db.dropDatabase() # 删除当前数据库
exit
1.5 停止MongoDB
systemctl stop mongod
# 通过管理员调用shutdown方法关闭
mongosh
use admin
db.shutdownServer()
1.6 卸载
-
删除软件包
sudo yum erase $(rpm -qa | grep mongodb-enterprise)
-
删除数据目录
sudo rm -r /var/log/mongodb sudo rm -r /var/lib/mongo
1.7 修复
MongoDB不正当停止可能会造成损坏,导致无法启动
vim /etc/mongod.conf # 打开配置文件,查看数据库与日志路径
rm /var/lib/mongo/mongod.lock
rm /var/log/mongodb/mongod.log
/usr/bin/mongod -f /etc/mongod.conf --repair
二 通过命令行mongo管理MongoDB
2.1 连接
-
连接本地默认端口
mongosh
-
连接单个
mongosh "mongodb://用户名@IP:端口/?authSource=数据库" mongosh --username 用户名 --password --authenticationDatabase 数据库 --host IP --port 端口
-
连接集群
mongosh "mongodb://IP:端口,IP:端口,IP:端口/?replicaSet=集群名&ssl=true" mongosh "mongodb+srv://域名" mongosh --ssl --host 集群名/IP:端口,IP:端口,IP:端口
2.2 自定义提示
2.2.1 自定义提示以显示操作数
mongo连接后执行
cmdCount = 1;
prompt = function() {
return (cmdCount++) + "> ";
}
2.2.2 自定义提示以显示数据库和主机名
mongo连接后执行
host = db.serverStatus().host;
prompt = function() {
return db+"@"+host+"$ ";
}
2.2.3 自定义提示以显示时间和文档计数
mongo连接后执行
prompt = function() {
return "Uptime:"+db.serverStatus().uptime+" Documents:"+db.stats().objects+" > ";
}
2.3 使用外部编译器
-
在mongo连接之前,设置 EDITOR 环境变量
export EDITOR=vim mongosh
-
定义函数
function myFunction () { }
-
打开编辑器编写函数
edit myFunction function myFunction() { print("This was edited"); }
-
查看
myFunction
2.4 修改查询操作返回的结果条数
默认为20,可以在连接后通过以下命令修改
DBQuery.shellBatchSize = 3;
2.5 帮助命令
-
连接前
mongosh -h mongosh --help
-
连接后
在后面追加上help()方法
2.6 执行JavaScript
-
执行片段
mongosh test --eval "printjson(db.getCollectionNames())" # 查询数据库 test 中集合的名称
-
执行脚本
mongosh localhost:27017/test myjsfile.js # 执行 myjsfile.js
三 CRUD
3.1 插入
执行插入操作时,如果该集合当前不存在,则插入操作将创建该集合。
在MongoDB中,存储在集合中的每个文档都需要一个唯一的 _id字段作为主键。如果插入的文档省略了该_id字段,则MongoDB驱动程序会自动为该字段生成一个ObjectId_id。这也适用于通过upsert:true的更新操作插入的文档。
MongoDB中的所有写操作在单个文档级别上都是原子性的
-
插入一个文档
db.inventory.insertOne( { item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } } )
-
插入多个文件
db.inventory.insertMany([ { item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } }, { item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } }, { item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } } ])
-
插入任意个文件
db.inventory.insert([ { item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } }, { item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } }, { item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } } ])
-
db.collection.update()与upsert: true 选项一起使用时。
-
db.collection.updateOne()与upsert: true选项一起使用时。
-
db.collection.updateMany()与upsert: true选项一起使用时。
-
db.collection.findAndModify()与upsert: true选项一起使用时。
-
db.collection.findOneAndUpdate()与upsert: true选项一起使用时 。
-
db.collection.findOneAndReplace()与upsert: true选项一起使用时 。
-
db.collection.save()。
-
db.collection.bulkWrite()。
3.2 查询
查询内容输出格式化使用 pretty()
3.2.1 普通查询
-
查询集合中的所有文档
db.inventory.find( {} )
-
完全匹配查询
db.inventory.find( { status: "D" } )
-
与(默认、省略)查询
```powershell db.inventory.find( { status: "A", qty: { $lt: 30 } } ) ```
-
in
db.inventory.find( { status: { $in: [ "A", "D" ] } } )
-
或查询
db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )
-
查询数组中包含某一个
db.inventory.find( { tags: "red" } )
-
查询数组中同时包含多个
db.inventory.find( { tags: { $all: ["red", "blank"] } } )
-
查询数组中至少有一个值大于25的
db.inventory.find( { dim_cm: { $gt: 25 } } )
-
查询一个元素可以满足大于15 条件,而另一个元素可以满足小于20 条件,或者一个元素可以满足以下两个条件
db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } )
3.2.2 查询数组
-
查询数组包含至少一个同时大于( g t ) 22 和 小 于 ( gt) 22和小于( gt)22和小于(lt)30的元素:
db.inventory.find( { dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } } } )
-
查询数组dim_cm中第二个元素大于25的所有文档:
db.inventory.find( { "dim_cm.1": { $gt: 25 } } )
-
查询数组tags有3个元素(长度/大小等于3)的文档
db.inventory.find( { "tags": { $size: 3 } } )
3.2.3 指定查询返回结果的字段
_id默认返回;
要返回的字段设置为1;
不返回的字段设置为0;
-
返回item,status与_id
db.inventory.find( { status: "A" }, { item: 1, status: 1 } )
-
返回item,status
db.inventory.find( { status: "A" }, { item: 1, status: 1, _id: 0 } )
-
返回除status和instock的所有字段
db.inventory.find( { status: "A" }, { status: 0, instock: 0 } )
-
返回内嵌文件的特定字段
db.inventory.find( { status: "A" }, { item: 1, status: 1, "size.uom": 1 } )
-
tags数组只返回从下标0开始的1个
db.inventory.find( { item: "journal" }, { tags: {$slice: 1} } )
-
tags数组只返回从下标1开始的2个
db.inventory.find( { item: "paper" }, { tags: {$slice: [1, 2]} } )
-
tags数组只返回从右向左数第3个开始,向右取2个
db.inventory.find( { item: "paper" }, { tags: {$slice: [-3, 2]} } )
3.2.4 null查询
-
查询item为null或不存在的(三个语句效果相同)
db.inventory.find( { item: null } ) db.inventory.find( { item : { $type: 10 } } ) # 官方文档说可以这样用,但实际不行,查询没有返回结果 db.inventory.find( { item : { $exists: false } } )
3.2.5 分页
跳过一行,从第二行开始查询两条数据
db.inventory.find({}).skip(1).limit(2)
3.2.6 排序
根据size数组里面的h排序,1是升序,-1降序
db.inventory.find({}).sort({"size.h": 1})
3.2.7 手动迭代游标查询
默认情况下,服务器将在闲置10分钟后或客户端用尽游标后自动关闭游标。
# 遍历打印所有
var myCursor = db.users.find( { type: 2 } );
while (myCursor.hasNext()) {
printjson(myCursor.next());
}
var myCursor = db.users.find( { type: 2 } );
myCursor.forEach(printjson);
# 转化为数组,打印下表为3的数据
var myCursor = db.inventory.find( { type: 2 } );
var documentArray = myCursor.toArray();
var myDocument = documentArray[3];
printjson(myDocument);
# 打印下表为1的数据
var myCursor = db.users.find( { type: 2 } );
var myDocument = myCursor[1];
printjson(myDocument);
3.2.8 聚合查询
-
过滤重复的数据
db.inventory.distinct( { status: "D" } )
-
查询符合条件的数据的条数
db.inventory.countDocuments( { status: "D" } )
-
估算条数,没有countDocuments精确
db.inventory.estimatedDocumentCount({})
3.3 更新
MongoDB中的所有写操作在单个文档级别上都是原子性的。
_id无法修改,并且_id字段永远是文档中的第一个字段
除修改字段名,更新操作不会对文档中字段进行重排序
更新操作符
运算符 | 样例 | 描述 |
---|---|---|
$inc | {$inc:{qty:20}} | qty字段值加20,字段不存在就新增一个默认值为0的,然后加20;如果值为负数则相当于减;用于整型,长整型,双精度浮点型 |
$set | {$set:{qty:10}} | qty字段值设为10,字段不存在时则新增字段,并且不受类型限制 |
$unset | {$unset:{aaa:true}} | 删除字段aaa |
$rename | {$rename:{aaa: “bbb”}} | 把字段aaa改为bbb,可同时修改多个;如果修改后的字段名在文档中已存在,就会覆盖以前的;同时还可以达到将字段在文档与子文档之间移动的效果 |
$setOnInsert | {$setOnInsert: {qty: 30}}, {upsert: true} | 与upsert一起使用,只有新增文档时才会生效,将qty设置为30 |
$currentDate | {$currentDate:{lastUpdate:true}} | 将字段lastUpdate设为当前时间 |
$min | {$min:{qty:10}} | 如果字段qty的值小于10,就将字段qty的值设置为10 |
$max | {$max:{qty:10}} | 如果字段qty的值大于10,就将字段qty的值设置为10 |
$mul | {$mul:{qty:10}} | 将字段qty的值乘以10 |
$ | {$ set: {“lengths.$ [element]”: 100}}, {arrayFilters: [{“element”: {$gte: 100}}]} | 定位到某一个元素,lengths数组中大于100的元素 |
$push | {$push:{tags:“B”}} | 添加“”B“”到数组tags中 |
$addToSet | {$addToSet:{tags:“B”}} | 如果数组tags中没有“”B“”,则添加“”B“”到数组中 |
$pop | {$pop: {tags: -1}} | -1为删除数组tags左边第一个,1为删除最后右边第一个,只能为1或-1 |
$pull | {$pull: {tags: “B”}} | 删除数组tags中所有的“”B“” |
$pullAll | {$pullAll: {tags: [“B”, “C”]}} | 从数组tags中删除所有的“”B“”,“”C“” |
$each | {$push: {tags: {$each: [“D”, “E”, “F”]}}} | 将"D", “E”, "F"每个都作为一个单独的个体,一次性加入tags数组中。如果没用$each,会把 [“D”, “E”, “F”]作为一个整体加入tags数组中;与 $push、 $addToSet一起使用 |
$slice | {$push: {tags: {$each: [“D”, “E”, “F”], $slice: 8}}}) | 切割,从左边(头)开始取8位,负数为从右边(后)开始;与$push、 $addToSet、 $each一起使用,保证数组长度 |
$sort | {$push: {aaa: {$each:[],$sort:{score:1}}}} | 数组aaa根据字段score升序排序 |
$bit | 位更新 |
3.3.1 更新
-
db.collection.update()
-
db.collection.updateOne()
-
db.collection.updateMany()
db.collection.update( <filter>, # 查询条件,根据查询条件找出要修改的文档,传{}空表示更新第一个文档 <update>, # 更新操作 { upsert: <boolean>, # 默认false,true是当没有匹配的文档是创建一个新的 writeConcern: <document>, # 写策略 collation: <document>, # 索引语音规则 arrayFilters: [ <filterdocument1>, ... ], # 过滤文档数组,用于确定更新操作要修改的数组中的具体元素 hint: <document|string> # 指定查询希望使用的索引字段,如果索引不存在会报错 multi: <boolean> # 默认false,只更新第一个文档,true更新所有符合条件的文档。updateOne、updateMany就是这个的默认值不同 } )
db.inventory.drop() db.inventory.insertMany( [ { item: "canvas", qty: 100, size: { h: 28, w: 35.5, uom: "cm" }, status: "A" }, { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" }, { item: "mat", qty: 85, size: { h: 27.9, w: 35.5, uom: "cm" }, status: "A" }, { item: "mousepad", qty: 25, size: { h: 19, w: 22.85, uom: "cm" }, status: "P" }, { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "P" }, { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" }, { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" }, { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }, { item: "sketchbook", qty: 80, size: { h: 14, w: 21, uom: "cm" }, status: "A" }, { item: "sketch pad", qty: 95, size: { h: 22.85, w: 30.5, uom: "cm" }, status: "A" } ] );
对于 u n s e t , unset, unset,currentDate等操作符对应的的bson中字段名作为key值,value值可以为任意值
db.inventory.update({}, {$set:{qty:200}}) db.inventory.update({item:"paper"},{$set:{qty:10}}) db.inventory.update({item:"paper"},{$inc:{qty:20}}) db.inventory.update({item:"paper"},{$inc:{qty:-20}}) db.inventory.update({item:"paper"},{$mul:{qty:10}}) db.inventory.update({item: "paper"}, {$setOnInsert: {qty: 30}}) db.inventory.update({item:"paper"},{$currentDate:{lastUpdate: true}}) db.inventory.update({item:"paper"},{$rename:{lastUpdate: "lastModify"}}) db.inventory.update({item: "paper"}, {$rename: {"size.h": "h"}}) db.inventory.update({item:"paper"},{$unset:{lastModify:true}}) db.inventory.update({item:"aaa"},{$currentDate:{lastUpdate:true}}) db.inventory.update({item:"aaa"},{$currentDate:{lastUpdate:true}},{upsert:true}) db.inventory.update({item:"aaa"},{$set:{tags:["A","B"]}}) db.inventory.update({item:"aaa"},{$push:{tags:"B"}}) db.inventory.update({item: "aaa"}, {$push: {tags: {$each: ["D", "E", "F"]}}}) db.inventory.update({item: "aaa"}, {$push: {tags: {$each: ["D", "E", "F"], $slice: 8}}}) db.inventory.update({item:"aaa"},{$addToSet:{tags:"B"}}) db.inventory.update({item:"aaa"},{$addToSet:{tags:"C"}}) db.inventory.update({item: "aaa"}, {$pop: {tags: -1}}) # 删除第一个 db.inventory.update({item: "aaa"}, {$pop: {tags: 1}}) # 删除最后一个 db.inventory.update({item: "aaa"}, {$pull: {tags: "B"}}) db.inventory.update({item: "aaa"}, {$pullAll: {tags: ["B", "C"]}}) db.inventory.update({item: "aaa"}, {$set: {"lengths.$[element]": 100}}, {arrayFilters: [{"element": {$gte: 100}}]}) # 将length数组中大于100的值改为100
3.3.2 替换
-
db.collection.replaceOne()
db.collection.replaceOne( <filter>, # 查询条件,根据查询条件找出要替换的文档,传{}空表示替换第一个文档 <replacement>, # 替换的文档 { upsert: <boolean>, # 默认false,true是当没有匹配的文档是创建一个新的 writeConcern: <document>, # 写策略 collation: <document>, # 索引语音规则 hint: <document|string> # 指定查询希望使用的索引字段,如果索引不存在会报错 } ) db.inventory.replaceOne({item:"canvas"},{item: "aaa"})
3.3.3 其他
- db.collection.findOneAndReplace()。
- db.collection.findOneAndUpdate()。
- db.collection.findAndModify()。
- db.collection.save()。
- db.collection.bulkWrite()。
3.4 删除
删除操作不会删除索引,即使从集合中删除所有文档也是如此。
3.4.1 删除文件
-
删除所有文件
db.inventory.deleteMany({})
-
删除符合条件的所有文件
db.inventory.deleteMany({ status : "A" })
-
删除符合条件的一个文档(第一个)
db.inventory.deleteOne( { status: "D" } )
-
移除
可以自定义删除一行还是所有,可以自定义写关注,可以对匹配到的要删除的数据进行排序等。
官方文档db.collection.remove( <query>, { justOne: <boolean>, writeConcern: <document>, collation: <document>, let: <document> // Added in MongoDB 5.0 } )
-
排序后删除并返回第一个
db.collection.findOneAndDelete( filter, options )
-
排序后修改第一个文档,并返回原来的第一个文档
db.collection.findAndModify({ query: <document>, sort: <document>, remove: <boolean>, update: <document or aggregation pipeline>, // Changed in MongoDB 4.2 new: <boolean>, fields: <document>, upsert: <boolean>, bypassDocumentValidation: <boolean>, writeConcern: <document>, collation: <document>, arrayFilters: [ <filterdocument1>, ... ], let: <document> // Added in MongoDB 5.0 });
3.5 批量写入操作
db.collection.bulkWrite() 方法提供了执行批量插入、更新和删除操作的能力。并且插入、更新、删除可以一起执行。
使用有序的操作列表,MongoDB 以串行方式执行操作。如果在处理其中一个写操作的过程中发生错误,MongoDB 将返回而不处理列表中任何剩余的写操作。
使用无序列表的操作,MongoDB 可以并行执行操作,但不能保证这种行为。如果在处理其中一个写操作的过程中发生错误,MongoDB 将继续处理列表中剩余的写操作。
默认情况下使用有序操作。要使用无序操作,设置 ordered : false。
示例:
try {
db.characters.bulkWrite(
[
{ insertOne :
{
"document" :
{
"_id" : 4, "char" : "Dithras", "class" : "barbarian", "lvl" : 4
}
}
},
{ insertOne :
{
"document" :
{
"_id" : 5, "char" : "Taeln", "class" : "fighter", "lvl" : 3
}
}
},
{ updateOne :
{
"filter" : { "char" : "Eldon" },
"update" : { $set : { "status" : "Critical Injury" } }
}
},
{ deleteOne :
{ "filter" : { "char" : "Brisbane" } }
},
{ replaceOne :
{
"filter" : { "char" : "Meldane" },
"replacement" : { "char" : "Tanys", "class" : "oracle", "lvl" : 4 }
}
}
]
);
}
catch (e) {
print(e);
}
3.6 文本搜索
对索引字段的内容进行搜索。
要使用文本搜索,必须先创建文本索引。一个集合只能有一个文本搜索索引,但该索引可以覆盖多个字段。
3.6.1 创建文本索引
为集合 stores 创建文本搜索索引(text),索引包括 name、description 两个字段,即从这两个字段的内容中搜索。
db.stores.createIndex( { name: "text", description: "text" } )
2.6.2 搜索
db.stores.find( { $text: { $search: "java coffee shop" } } ) # 单词搜索,空格分隔
db.stores.find( { $text: { $search: "\"coffee shop\"" } } ) # 短语搜索,用双引号包裹,\ 反斜杠转义
db.stores.find( { $text: { $search: "java shop -coffee" } } ) # 通过 - 杠排除
db.stores.find(
{ $text: { $search: "java coffee shop" } },
{ score: { $meta: "textScore" } }
).sort( { score: { $meta: "textScore" } } ) # 排序,根据分数排序,默认不排序
四 聚合操作
聚合操作处理多个文档并返回计算结果。比如分组求和等
4.1 聚合管道
db.orders.aggregate( [
{ $match: { status: "urgent" } },
{ $group: { _id: "$productName", sumQuantity: { $sum: "$quantity" } } }
] )
- $match:匹配,即找到集合 orders 中所有字段 status 的值为 urgent 的文档。
- $group:分组。对 $match 中匹配到的文档,根据字段 productName 进行分组。
- $sum:求和。对分组后的文档,对字段 quantity 求和
4.2 单一目的聚合操作
通过其他收集方法实现
五 安全
5.1 SCRAM 认证
Salted Challenge Response Authentication Mechanism (SCRAM)是 MongoDB 的默认身份验证机制。
5.1.1 用户
5.1.1.1 创建管理员
use admin
db.createUser(
{
user: "root",
pwd: passwordPrompt(), // 也可以直接写密码,但不够安全。passwordPrompt() 可以打开密码输入模式
roles: [
{ role: "root", db: "admin" }
]
}
)
db.createUser(
{
user: "admin",
pwd: passwordPrompt(), // 也可以直接写密码,但不够安全。passwordPrompt() 可以打开密码输入模式
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" }
]
}
)
5.1.1.2 创建普通用户
use test
db.createUser(
{
user: "myTester",
pwd: passwordPrompt(), // or cleartext password
roles: [ { role: "readWrite", db: "test" },
{ role: "read", db: "reporting" } ]
}
)
5.1.1.3 查看用户
查看admin数据库中的system.user集合
use admin
db.system.users.find()
db.system.users.find({user: "admin"})
5.1.1.4 用户操作命令
命令 | 注释 |
---|---|
createUser | 创建一个新用户。 |
dropAllUsersFromDatabase | 删除与数据库关联的所有用户。 |
dropUser | 删除单个用户。 |
grantRolesToUser | 向用户授予角色及其权限。 |
revokeRolesFromUser | 从用户中删除角色。 |
updateUser | 更新用户的数据。 |
usersInfo | 返回有关指定用户的信息。 |
db.auth() | 向数据库验证用户。 |
db.changeUserPassword() | 更改现有用户的密码。 |
db.dropAllUsers() | 删除与数据库关联的所有用户。 |
db.getUser() | 返回有关指定用户的信息。 |
db.getUsers() | 返回有关与数据库关联的所有用户的信息。 |
passwordPrompt() | 提示输入密码作为在各种mongosh用户身份验证/管理方法中直接指定密码的替代方法。 |
5.1.2 角色
5.1.2.1 内置角色
5.1.2.2 自定义角色
5.1.2.3 角色管理命令
命令 | 注释 |
---|---|
createRole | 创建角色并指定其权限。 |
dropRole | 删除用户定义的角色。 |
dropAllRolesFromDatabase | 从数据库中删除所有用户定义的角色。 |
grantPrivilegesToRole | 为用户定义的角色分配权限。 |
grantRolesToRole | 指定用户定义的角色从中继承特权的角色。 |
invalidateUserCache | 刷新用户信息的内存缓存,包括凭据和角色。 |
revokePrivilegesFromRole | 从用户定义的角色中删除指定的权限。 |
revokeRolesFromRole | 从用户定义的角色中删除指定的继承角色。 |
rolesInfo | 返回指定角色的信息。 |
updateRole | 更新用户定义的角色。 |
db.getRole() | 返回指定角色的信息。 |
db.getRoles() | 返回数据库中所有用户定义角色的信息。 |
5.1.3 开启安全鉴权模式
修改配置文件 /etc/mongod.conf(默认),添加:
security:
authorization: enabled
开启安全模式之后,可以连接MongoDB,但是无法操作数据库。
5.1.4 通过用户密码连接MongoDB
mongo -u admin -p
5.2 其他认证方式
MongoDB还支持x.509、Kerberos 身份验证、LDAP 代理验证、内部/会员身份验证
5.3 集合级访问控制
六 主从复制
七 分片
八 MongoDB Compass(可视化工具)
8.1 下载
从官网下载。
8.2 连接
九 集成springboot
-
添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
-
配置数据源
spring: data: mongodb: # host: 192.168.10.128 # port: 27017 # username: admin # password: admin # database: test uri: mongodb://root:root@192.168.10.128:27017/test?authSource=admin&readPreference=primary&serverSelectionTimeoutMS=2000&appname=MongoDB%20Compass&directConnection=true&ssl=false
-
注入 MongoTemplate
@Autowired private MongoTemplate mongoTemplate;
-
使用
import com.guoli.mongodbstudy.pojo.Student; import com.mongodb.client.result.DeleteResult; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import java.util.List; @SpringBootTest class MongodbStudyApplicationTests { @Autowired private MongoTemplate mongoTemplate; @Test void insert() { // mongoTemplate.insert("{\"name\": \"zs\", \"age\": 18, \"source\": 80.6}", "student"); for (int i = 0; i < 9; i++) { Student s = mongoTemplate.insert(new Student(i, "ls" + i, 20 + i, 90.5 + i)); System.out.println(s); } } @Test void findAll() { List<Student> students = mongoTemplate.findAll(Student.class); students.forEach(System.out::println); } @Test void findById() { Student student = mongoTemplate.findById(1, Student.class); System.out.println(student); } @Test void find() { Query query = new Query(); // 指定返回结果包含的字段 // query.fields().include("name"); // 指定返回结果不包含的字段 // query.fields().exclude("name"); // 根据字段查找 // query.addCriteria(new Criteria().and("age").is(21)); // query.addCriteria(new Criteria().and("name").regex("l.*")); query.addCriteria(new Criteria("age").is(21)).addCriteria(new Criteria("name").regex("l.*")); // 大于、小于或等于 // query.addCriteria(Criteria.where("age").gt(25)); // query.addCriteria(Criteria.where("age").lte(25)); query.collation() List<Student> students = mongoTemplate.find(query, Student.class); students.forEach(System.out::println); } @Test void findSort() { Query query = new Query(); query.with(Sort.by(Sort.Direction.DESC, "age")); List<Student> students = mongoTemplate.find(query, Student.class); students.forEach(System.out::println); } @Test void findPage() { Query query = new Query(); query.with(PageRequest.of(1, 3)); List<Student> students = mongoTemplate.find(query, Student.class); students.forEach(System.out::println); } @Test void remove() { Query query = new Query(); DeleteResult deleteResult = mongoTemplate.remove(query, Student.class); System.out.println(deleteResult.wasAcknowledged()); System.out.println(deleteResult.getDeletedCount()); } @Test void drop() { mongoTemplate.dropCollection(Student.class); } }