MongoDB基本操作
1.操作说明
CRUD操作是create(创建), read(读取), update(更新)和delete(删除) 文档。
MongoDB不支持SQL但是支持自己的丰富的查询语言。
在MongoDB中,存储在集合中的每个文档都需要一个唯一的 _id字段,作为主键。如果插入的文档省略了该_id字段,则MongoDB驱动程序将自动为该字段生成一个ObjectId_id。也用于通过更新操作插入的文档upsert: true.如果文档包含一个_id字段,该_id值在集合中必须是唯一的,以避免重复键错误。
在MongoDB中,插入操作针对单个集合。 MongoDB中的所有写操作都是在单个文档的级别上进行的
2.基本操作
show databases/show dbs #查看库列表
show tables/show collections #查看所有的集合
use admin #切换库(没有的库也可以进行切换,没有数据是看不到)
db #查看当前库
show users #打印当前数据库的用户列表
test:登录时默认存在的库
admin库:系统预留库,MongoDB系统管理库
local库:本地预留库,存储关键日志
config库:MongoDB配置信息库
3.插入数据
1)单条数据插入
db.test.insert({"name":"lhd","age":18,"sex":"男"})
db.test.insert({"name":"lhd","age":18,"sex":"男","address":"上海浦东新区"})
db.test.insertOne({"name":"lhd","age":18,"sex":"男","address":"上海浦东新区"})
2)多条数据插入
db.inventory.insertMany( [
{ "name": "lhd", "age": 18, "figure": { "h": 182, "w": 200 }, "size": "big" },
{ "name": "qiudao", "age": 88, "figure": { "h": 120, "w": 160 }, "size": "very bittle" },
{ "name": "zengdao", "age": 18, "figure": { "h": 180, "w": 160 }, "size": "nomel" },
]);
4.查询数据
1)查询所有数据
> db.test.find()
{ "_id" : ObjectId("5ecdcdac13a4155a65ecb332"), "name" : "lhd", "age" : 18, "sex" : "男" }
{ "_id" : ObjectId("5ecdcdc413a4155a65ecb333"), "name" : "lhd", "age" : 18, "sex" : "男", "address" : "上海浦东新区" }
{ "_id" : ObjectId("5ecdcdd213a4155a65ecb334"), "name" : "lhd", "age" : 18, "sex" : "男" }
{ "_id" : ObjectId("5ecdcdd813a4155a65ecb335"), "name" : "lhd", "age" : 18, "sex" : "男", "address" : "上海浦东新区" }
2)查询单条数据
> db.test.findOne()
{
"_id" : ObjectId("5ecdcdac13a4155a65ecb332"),
"name" : "lhd",
"age" : 18,
"sex" : "男"
}
3)按条件查询
#如果查询条件为数字,不需要加引号
> db.test.findOne({"name" : "lhd"})
{
"_id" : ObjectId("5ecdcdac13a4155a65ecb332"),
"name" : "lhd",
"age" : 18,
"sex" : "男"
}
4)查询多条件
#并且的多个条件
> db.inventory.find({"figure.h":120,"size":"very bittle"})
> db.inventory.find(
{
"figure.h":120,
"size":"very bittle"
}
)
#表示多条件或者
> db.inventory.find({$or:[{"figure.h":120},{"size":"big"}]})
> db.inventory.find(
{
$or [
{"figure.h":120},
{"size":"big"}
]
}
)
5)条件加范围的查询
> db.inventory.find({$or:[{"figure.h":{$lt:130}},{"size":"big"}]})
> db.inventory.find(
{
$or [
{"figure.h":{$lt:130}},
{"size":"big"}
]
}
)
5.修改数据
1)修改单个数据
> db.inventory.updateOne({"name":"qiudao"},{$set:{"figure.h":130}})
> db.inventory.updateOne(
#条件
{"name":"qiudao"},
{
$set:
#修改的值
{"figure.h":130}
}
)
2)修改多条数据
> db.table.updateMany({name:"niulei"},{$set:{age:"18"}})
{ "acknowledged" : true, "matchedCount" : 4, "modifiedCount" : 3 }
6.索引
1)查看执行计划
> db.inventory.find().explain()
{ #查询计划
"queryPlanner" : {
#计划版本
"plannerVersion" : 1,
#被查询的库和集合
"namespace" : "test2.inventory",
#查询索引设置
"indexFilterSet" : false,
#查询条件
"parsedQuery" : {
},
#成功的执行计划
"winningPlan" : {
#全表扫描
"stage" : "COLLSCAN",
#查询方向
"direction" : "forward"
},
#拒绝的计划
"rejectedPlans" : [ ]
},
#服务器信息
"serverInfo" : {
"host" : "redis01",
"port" : 27017,
"version" : "3.6.13",
"gitVersion" : "db3c76679b7a3d9b443a0e1b3e45ed02b88c539f"
},
"ok" : 1
}
COLLSCAN 全表扫描
IXSCAN 索引扫描
2)创建索引
> db.inventory.createIndex({"age":1},{background:true})
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
#添加索引
createIndex({索引的名称:1}) :1表示正序,-1表示倒序
#创建方式
1.前台方式
缺省情况下,当为一个集合创建索引时,这个操作将阻塞其他的所有操作。即该集合上的无法正常读写,直到索引创建完毕
任意基于所有数据库申请读或写锁都将等待直到前台完成索引创建操作
2.后台方式
将索引创建置于到后台,适用于那些需要长时间创建索引的情形
这样子在创建索引期间,MongoDB依旧可以正常的为提供读写操作服务
等同于关系型数据库在创建索引的时候指定online,而MongoDB则是指定background
其目的都是相同的,即在索引创建期间,尽可能的以一种占用较少的资源占用方式来实现,同时又可以提供读写服务
后台创建方式的代价:索引创建时间变长
#规范
1.如果要查询的内容都是最近的,那建立索引就用倒序,如果要通盘查询那就用正序。
2.比如说一个数据集合查询占的比较多就用索引,如果查询少而是插入数据比较多就不用建立索引。因为:当没有索引的时候,插入数据的时候MongoDB会在内存中分配出一块空间,用来存放数据。当有索引的时候在插入数据之后还会给自动添加一个索引,浪费了时间。
3.不是所有数据都要建立索引,要在恰当并且需要的地方建立才是最好的。
4.大数量的排序工作时可以考虑创建索引。
3)查看索引
> db.inventory.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test2.test2"
},
{
"v" : 2,
"key" : {
"age" : 1
},
"name" : "name_1",
"ns" : "test2.test2",
"background" : true
}
]
4)再次查看执行计划
> db.inventory.find({"age":{$lt:40}}).explain()
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
#走索引了
"stage" : "IXSCAN",
6.删除
1)删除单条数据
> db.inventory.deleteOne({"name":"lhd"})
{ "acknowledged" : true, "deletedCount" : 1 }
2)删除多个数据
> db.inventory.deleteMany({"name":"lhd"})
3)删除索引
> db.test.dropIndex({ age: 1 })
{
"ok" : 0,
"errmsg" : "ns not found",
"code" : 26,
"codeName" : "NamespaceNotFound"
}
4)删除集合
#先确认自己在哪个库
> db
test2
#确认集合
> show tables;
inventory
test
#删除集合
> db.inventory.drop()
true
5)删除库
#先确认自己在哪个库
> db
test2
#删除库
> db.dropDatabase()
mongo工具
mongo #登录命令
mongodump #备份导出,全备(数据时压缩过的)
mongorestore #恢复数据
mongostat #查看运行状态的
mongod #启动命令
mongoexport #备份,导出json格式
mongoimport #恢复数据
mongos #集群分片命令
mongotop #查看运行状态
1.mongostat命令
#不加任何参数时,每秒访问一次
[mongo@redis01 ~]$ mongostat
insert query update delete getmore command dirty used flushes vsize res qrw arw net_in net_out conn time
*0 *0 *0 *0 0 2|0 0.0% 0.0% 0 972M 56.0M 0|0 1|0 158b 60.9k 1 May 27 11:23:08.248
insert #每秒插入数据的数量
query #每秒查询操作的数量
update #每秒更新数据的数量
delete #没面删除操作的数量
getmore #每秒查询游标时的操作数
command #每秒执行的命令数
dirty #脏数据占缓存的多少
used #使用中的缓存
flushes
#在 wiredtiger引擎,表示轮询间隔
#在MMapv1引擎,表示每秒写入磁盘次数
vsize #虚拟内存使用量
res #物理内存使用量
qrw #客户端等待读数据的队列长度
arw #客户端等待写入数据的队列长度
net_in #网络进流量
net_out #网络出流量
conn #连接总数
time #时间
#一般该命令搭配 mongotop 命令使用,可以显示每个集合的响应速度
用户授权认证
1.授权命令
用户管理界面
要添加用户, MongoDB提供了该db.createUser()方法。添加用户时,您可以为用户分配色以授予权限。
注意:
在数据库中创建的第一个用户应该是具有管理其他用户的权限的用户管理员。
您还可以更新现有用户,例如更改密码并授予或撤销角色。
db.auth() 将用户验证到数据库。
db.changeUserPassword() 更改现有用户的密码。
db.createUser() 创建一个新用户。
db.dropUser() 删除单个用户。
db.dropAllUsers() 删除与数据库关联的所有用户。
db.getUser() 返回有关指定用户的信息。
db.getUsers() 返回有关与数据库关联的所有用户的信息。
db.grantRolesToUser() 授予用户角色及其特权。
db.removeUser() 已过时。从数据库中删除用户。
db.revokeRolesFromUser() 从用户中删除角色。
db.updateUser() 更新用户数据。
2.创建用户和角色
[mongo@db01 ~]$ mongo
> use admin
> db.createUser({user: "admin",pwd: "123456",roles:[ { role: "root", db:"admin"}]})
Successfully added user: {
"user" : "admin",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
3.查看用户
> db.getUsers()
[
{
"_id" : "test.admin",
"userId" : UUID("b840b96c-3442-492e-a45f-6ca7dff907fd"),
"user" : "admin",
"db" : "test",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
]
4.配置开启认证
[root@redis01 ~]# vim /server/mongo_27017/conf/mongodb.conf
security:
authorization: enabled
#重启
[mongo@redis01 ~]$ mongod -f /server/mongo_27017/conf/mongodb.conf --shutdown
[mongo@redis01 ~]$ mongod -f /server/mongo_27017/conf/mongodb.conf
5.配置认证以后查操作不了
> show databases;
2020-05-27T11:41:06.186+0800 E QUERY [thread1] Error: listDatabases failed:{
"ok" : 0,
"errmsg" : "there are no users authenticated",
"code" : 13,
"codeName" : "Unauthorized"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:67:1
shellHelper.show@src/mongo/shell/utils.js:860:19
shellHelper@src/mongo/shell/utils.js:750:15
@(shellhelp2):1:1
6.使用账号密码连接
[mongo@redis01 ~]$ mongo -uadmin -p --authenticationDatabase admin
MongoDB shell version v3.6.13
Enter password:
> show databases;
admin 0.000GB
config 0.000GB
local 0.000GB
test 0.000GB
test2 0.000GB
7.创建普通用户
> use test
> db.createUser(
{
user: "test",
pwd: "123456",
roles: [ { role: "readWrite", db: "write" },
{ role: "read", db: "read" } ]
}
)
8.创建测试数据
use write
db.write.insert({"name":"linhaoda","age":17,"ad":"上海浦东新区"})
db.write.insert({"name":"linhaoda","age":17,"ad":"上海浦东新区"})
db.write.insert({"name":"haoda","age":18,"ad":"上海浦东新区"})
db.write.insert({"name":"linda","age":18,"ad":"上海浦东新区"})
db.write.insert({"name":"linhao","age":18,"ad":"上海浦东新区","sex":"boy"})
use read
db.read.insert({"name":"linhaoda","age":17,"ad":"上海浦东新区"})
db.read.insert({"name":"linhaoda","age":17,"ad":"上海浦东新区"})
db.read.insert({"name":"haoda","age":18,"ad":"上海浦东新区"})
db.read.insert({"name":"linda","age":18,"ad":"上海浦东新区"})
db.read.insert({"name":"linhao","age":18,"ad":"上海浦东新区","sex":"boy"})
9.验证
mongo -utest -p --authenticationDatabase test
use write
db.write.find()
db.write.insert({"name":"linhaoda","age":17,"ad":"上海浦东新区"})
use read
db.read.find()
db.read.insert({"name":"linhaoda","age":17,"ad":"上海浦东新区"})
10.修改用户密码
#修改用户信息
db.updateUser("test",{pwd:"123"})
#修改密码
db.changeUserPassword("admin","123")
MongoDB基本操作