mongodb入门篇
[TOC]
基本操作
登入与登出
#.登陆测试
/opt/mongodb/bin/mongosh -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin --host 127.0.0.1 --port 3717 admin
//.查看版本
> db.version();
6.0.6
//.退出交互式界面
> quit
数据库的管理
//.创建数据库,mongodb没有创建数据库的命令,通过use切换上下文并写入数据时,如果数据库不存在,则会自动创建
use db1;
db.createCollection("aaa");
//.查看数据库清单
show dbs;
show databases;
//.切换上下文数据库
use db1;
//.显示当前数据库名称
db;
db.getName();
//.查看所有数据库的大小
show dbs;
db.adminCommand({listDatabases:1}).databases.forEach(function(item){printjson(item)});
//.查看所有数据库的大小
db.adminCommand({listDatabases:1}).databases.forEach(function(item){var db_name=item.name; var db_size=db.getSiblingDB(db_name).stats(1024*1024).storageSize; var db_st={name:db_name, storage_size:db_size}; printjson(db_st);});
//.拷贝数据库(mongodb 4.0 之后不再支持)
//.语法:db.copyDatabase(<fromdb>, <todb>, <fromhost>, <username>, <password>, <mechanism>);
//.示例:db.copyDatabase("db1","db2","192.168.31.101:3717","dba_admin","cf_rB1NKCzbaQuPH","MONGODB-CR")
//.示例:db.copyDatabase('db1','db1_bak');
//.删除当前数据库()
use db1;
db;
db.dropDatabase();
数据表的管理
//.切换上下文数据库
use db1;
//.创建数据表-显示创建
db.createCollection("aaa");
//.创建数据表-隐示创建
db.aaa.insert({"name":"sam"});
//.创建数据表(capped为true指定自动覆盖、size指定最大字节数、max指定最大行数为3,测试写入5行,查看只有第3-5行)
db.createCollection("bbb", {capped: true, size: 65536, max: 3});
for(var i=1;i<=5;i++){db.bbb.insert({"username":"user"+i,"created_at":new Date()});};
db.bbb.find();
//.查看当前db的数据表清单
show tables;
show collections;
db.getCollectionNames();
//.查看当前db的表数量及库大小
db.stats();
db.stats(1024); //.以KB为单位的库大小
db.stats(1048576); //.以MB为单位的库大小
db.stats(1073741824); //.以GB为单位的库大小
//.查看当前库所有表的行数及大小
db.getCollectionNames().forEach(print();)
var t=db.getCollectionNames()
t.forEach(function(item){
var coll_info=db.getCollection(item).stats(1024*1024*1024)
var coll_stats={coll_name:item, record_count:coll_info.count, stroage_size:coll_info.storageSize, index_size:coll_info.totalIndexSize}
printjson(coll_stats)
});
//.查看表名与文件名的对应关系(uri对应的就是该表对应的文件名)
db.aaa.stats();
//.通过stats查看表的状态,包括行数/大小等
db.aaa.stats();
db.aaa.dataSize();
db.aaa.stats().indexSizes;
db.aaa.stats().count;
db.aaa.stats().size;
db.aaa.stats().avgObjSize;
db.aaa.stats().storageSize;
//.备份数据表(mongodb 5.0 之后不再支持)
// db.aaa.copyTo("aaa_bak");
//.备份数据表(新表会自动创建)
db.aaa.find().forEach(function(x){db.aaa_bak.insert(x)});
//.把源库db1中的aaa表复制到目标库db2的bbb表中
use db1;
db.aaa.find().forEach(function(x){db.getSiblingDB('db2')['bbb'].insert(x);});
//.修改表名-方式1
use db1;
db.aaa.renameCollection("bbb");
//.修改表名-方式2
use admin;
db.runCommand({'renameCollection':'db1.bbb','to':'db1.aaa'});
//.删除数据表
db.aaa.drop();
- 以下是一些特殊表的处理办法:
//.如果表名为数字或以数字开头,则操作表的时候需要在表名前后添加引号,不可以用 db.表名.countDocuments(); 的方式
db.createCollection("10001");
db.getCollection("10001").insert({"name":"sam"});
db.getCollection('10001').find();
增删改查
- 修改数据的话,请注意 save / update / replace 之间的区别
insert 与 save
- mongodb 5.0 之后不再支持 db.collection.save,请替换使用 insertOne、insertMany、bulkWrite
//.切换上下文数据库
use db1;
//.写入数据-显示写入(建表+写入)
db.createCollection("aaa");
db.getCollection("aaa").insert({"name":"sam"});
//.写入数据-隐示写入(建表+写入)
db.aaa.insert({"name":"sam"});
//.插入单条数据
db.aaa.insertOne({name:'sam',qty:100});
//.插入多条数据
db.aaa.insertMany([{name:'joy',qty:25},{name:'joy',qty:25}]);
//.早期版本save会自动建表(mongodb 5.0 之后不再支持)
// db.aaa.save({"id":110,"name":"tom"});
//.批量写操作
db.aaa.bulkWrite( [
{ insertOne: { document: { name: "tom", age: 6 } } },
{ insertOne: { document: { name: "sam", age: 10 } } },
{ updateOne: { filter: { name: "joy" }, update: { $set: { age: 8 } } } },
{ deleteOne: { filter: { name: "poy"} } }
] );
//.批量写入(示例批量写入1w行)
for(var i=1;i<=10000;i++){db.aaa.insert({"username":"user"+i,"created_at":new Date()});};
db.aaa.count();
find
//.切换上下文数据库
use db1;
//.查看表的行数
db.aaa.count();
db.aaa.countDocuments();
db.aaa.countDocuments({"name":"sam"});
//.限制返回的行数(示例只返回10行)
db.aaa.find().limit(10);
db.aaa.find({"name":"sam"}).limit(10);
//.返回第一条满足条件的数据,等价于 db.aaa.find().pretty().limit(1)
db.aaa.findOne();
db.aaa.find().pretty().limit(1)
//.返回3条记录并打印信息
db.aaa.drop();
db.aaa.insertMany([{name:"tom",city:"shanghai",age:18},{name:"joy",city:"beijing",age:25}]);
db.aaa.find().limit(3).forEach(function(aaa) {print(aaa.name + ' age is ' + aaa.age)});
//.特定字段返回(_id字段总是会被返回)
db.aaa.drop();
db.aaa.insertMany([{name:"tom",city:"shanghai",age:18},{name:"joy",city:"beijing",age:25}]);
db.aaa.find({}, {name:1});
db.aaa.find({}, {name:true});
db.aaa.find({city:"shanghai",name:"tom"}, {name:1, age:1});
//.排除特定字段返回(将字段设置为0则不再显示)
db.aaa.find({}, {age:0});
db.aaa.find({}, {age:false});
db.aaa.find({city:"shanghai",name:"tom"}, {_id:0, age:0});
//.使用sort排序
db.aaa.drop();
db.aaa.insertMany([{name:"tom",city:"shanghai",age:18},{name:"joy",city:"beijing",age:25}]);
db.aaa.find({}, {name:1,age:1}).sort({age: 1}); //.升序
db.aaa.find({}, {name:1,age:1}).sort({age: -1}); //.降序
//.查询 age > 19 and age < 39 的数据
db.aaa.find({age:{$gt:19, $lt:39}});
//.查询 name <> "kugo" and age >= 20 的数据
db.aaa.find({name: {$ne: "kugo"}, age: {$gte: 20}});
//.查询 age in (19,29) 的数据
db.aaa.find({age: {$in: [19,25]}});
//.查询 age取模10等于0 的数据
db.aaa.drop();
db.aaa.insertMany([{name:"tom",city:"shanghai",age:18},{name:"joy",city:"beijing",age:20}]);
db.aaa.find({age:{$mod:[10,0]}});
//.查询 city like %jing% 的数据
db.aaa.find({city:{$regex:"jing"}}).limit(20);
//.查询 city <> bei% 的数据
db.aaa.find({city: {$not: /^bei.*/}});
//.查询9-39岁、city为shanghai的name,age字段
db.aaa.find({age:{$gt:9, $lt:39},city:"shanghai"}, {_id:0, name:1,age:1}).limit(10);
//.查找name为tom或sam,age大于20、小于50的数据
db.aaa.drop();
db.aaa.insertMany([{name:'tom',age:18},{name:'tom',age:25},{name:'sam',age:30}]);
db.aaa.find({'$or':[{"name":'tom'},{"name":'sam'}],"age":{'$gt':20,'$lt':80}});
//.指定列去重
db.aaa.drop();
db.aaa.insertMany([{name:'tom',qty:18},{name:'tom',qty:25},{name:'joy',qty:30}]);
db.aaa.distinct("name");
update 与 replace
//.切换上下文数据库
use db1;
//.仅更新第一条满足条件的数据
db.aaa.updateOne({"name":"joy"},{$set:{"qty":100}});
//.更新符合条件的所有数据
db.aaa.updateMany({"name":"joy"},{$set:{"qty":200}});
//.字段改名,示例:将name为tom的age字段重命名为age2
db.aaa.drop();
db.aaa.insertMany([{"name":"tom",age:18},{"name":"joy",age:25}]);
db.aaa.updateMany({name:"tom"},{$rename:{"age":"age2"}});
//.删除字段,示例:将name为tom的年龄字段删除
db.aaa.drop();
db.aaa.insertMany([{"name":"tom",age:18},{"name":"joy",age:25}]);
db.aaa.updateMany({name:"tom"},{$unset:{age:1}});
//.数字字段增加value,示例:将name为tom的age增加10
db.aaa.drop();
db.aaa.insertMany([{"name":"tom",age:18},{"name":"joy",age:25}]);
db.aaa.updateMany({name:"tom"},{$inc:{age:10}});
//.洗数据 - 将满足条件的数据(name为joy)字段b更新为字段a的内容
db.aaa.drop();
db.aaa.insertMany([{"name":"tom",age:18,qty:10},{"name":"joy",age:25,qty:11}]);
db.aaa.find().forEach(function(item){db.aaa.updateMany({"name":"joy"},{"$set":{"qty":item.age}})});
//.替换第一条满足条件的数据,可替换除 _id 之外的所有内容
db.aaa.replaceOne({name:"joy"}, {name:"joy",age:31});
//.模糊更新,将 testbank-file.oss-cn-shanghai.aliyuncs.com 替换为 testbank-file01.oss-cn-shanghai.aliyuncs.com
db.aaa.find({con:{$regex:"testbank-file.oss-cn-shanghai.aliyuncs.com"}}).count(); //.确认一下受影响的行数
db.aaa.find().forEach(function(x){db.aaa_20210202_bak.insert(x)}); //.备份一下受影响的数据
db.aaa.find({'con':{'$regex': "testbank-file.oss-cn-shanghai.aliyuncs.com"}}).forEach(
function(item) {
var tmp = String(item.con)
tmp = tmp.replace('testbank-file.oss-cn-shanghai.aliyuncs.com','testbank-file01.oss-cn-shanghai.aliyuncs.com')
if (tmp == null){
print(item.con)
}
item.con = tmp;
db.aaa.save(item);
}
);
delete 与 remove
//.切换上下文数据库
use db1;
//.删除符合条件的所有数据(后续版本会废弃)
db.aaa.find({"name":"sam"}).count();
db.aaa.remove({"name":"sam"});
//.仅删除第一条符合条件的数据
db.aaa.deleteOne({name:'sam'});
//.删除符合条件的所有数据,比如name为joy
db.aaa.drop();
db.aaa.insertMany([{"name":"tom",age:18},{"name":"joy",age:25}]);
db.aaa.deleteMany({"name":"joy"});
//.删除符合条件的所有数据,比如某个时间区间
db.aaa.drop();
db.aaa.insertMany([{"name":"tom","created_at":"2020-12-24T12:08:11.063Z"}]);
db.aaa.insertMany([{"name":"joy","created_at":"2022-12-24T12:08:11.063Z"}]);
db.aaa.remove({"created_at":{$gte:"2018-07-01",$lte:"2021-08-01"}});
db.aaa.remove({"created_at":{$regex:".*2022-12.*"}});
//.清空表
db.aaa.remove({});
db.aaa.deleteMany({});
账号的管理
createUser
//.示例1:创建超级管理员账号(超级权限,只能在admin数据库中可用)
use admin;
db.createUser({user:'rwuser',pwd:'rIFz_1Se4B7pBK6Z',roles:['root']},{w:'majority',wtimeout:5000});
db.createUser({user:'dba_admin',pwd:'cf_rB1NKCzbaQuPH',roles:[{role:'root',db:'admin'}]});
show users;
//.示例2:创建备份帐号
use admin;
db.createUser({user:"dba_backup",pwd:"Admin_369",roles:[{"role":"backup","db":"admin"}]});
//.示例3:创建全局读写账号(全局角色,只能在admin数据库中可用)
use admin;
db.createUser({user:"dba_admin_rw",pwd:"Admin_147",roles:[{"role":"readWriteAnyDatabase","db":"admin"}]});
//.示例4:创建全局只读账号(全局角色,只能在admin数据库中可用)
use admin;
db.createUser({user:"dba_admin_r",pwd:"Admin_258",roles:[{role:"readAnyDatabase", db:"admin"}]});
//.示例5:创建业务读写账号
use bigdata;
db.createUser({user:"user_bigdata_push",pwd:"dw_RX2a_6GemCf7u",roles:[{"role":"readWrite","db":"bigdata"}],passwordDigestor:"server"});
//.示例6:创建业务只读账号
use bigdata;
db.createUser({user:"user_bigdata_readonly",pwd:"dw_iuDIfQzWgVb9G",roles:[{"role":"read","db":"bigdata"}],passwordDigestor:"server"});
修改账号
//.修改密码
use bigdata;
db.changeUserPassword("user_bigdata_readonly","Aa_123456");
db.updateUser("user_bigdata_readonly",{pwd:"Aa_123456"});
//.修改权限-通过grant与revoke
use bigdata;
db.grantRolesToUser("user_bigdata_readonly",[{role:"readWrite",db:"db1"},{role:"read",db:"db2"}]);
db.revokeRolesFromUser("user_bigdata_readonly",[{role:"read",db:"db2"}]);
//.修改权限-通过updateUser
use bigdata;
db.updateUser("user_bigdata_readonly",{roles:[{role:"readWrite",db:"db1"}, {role:"readWrite",db:"db2"}]});
db.updateUser("user_bigdata_readonly",{roles:[{role:"read",db:"db1"}]});
//.切换账号(注:先在认证库下面db.auth(),然后再use切换上下文)
use admin;
db.auth("dba_admin_r","Admin_258");
use db1;
show tables;
//.查看全局账号
use admin;
db.system.users.find();
db.system.users.find({}, {name:1}); //.仅显示name
db.system.users.find({'db':'admin'}); //.根据db查用户
db.system.users.find({'user':'dba_admin'}); //.根据name查用户
//.查看当前库下的账号
use db1;
show users;
dropUser
//.删除用户
use bigdata;
db.dropUser("user_bigdata_push");
show users;
//.删除用户
use admin;
db.system.users.remove({user:"user_bigdata_readonly"});
show users;
- Windows登录mongodb及查看监控
cd /d d:\sqldata\mongodb27017\bin
.\mongo.exe --authenticationDatabase admin -u dba_admin -p cf_rB1NKCzbaQuPH
cd /d d:\sqldata\mongodb27017\bin
.\mongostat.exe -uroot --authenticationDatabase=admin -u dba_admin -p cf_rB1NKCzbaQuPH
- 【角色说明】
角色名称 | 角色类型 | 角色权限 | 备注 |
---|---|---|---|
read | 数据库用户角色 | 允许用户读取指定数据库 | - |
readWrite | 数据库用户角色 | 允许用户读写指定数据库 | - |
dbAdmin | 数据库管理角色 | 允许用户在指定数据库中执行管理函数,如索引创建、查看统计等 | - |
userAdmin | 数据库管理角色 | 允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户 | - |
dbOwner | 数据库管理角色 | 允许在当前DB中执行任意操作 | - |
backup | 备份恢复角色 | - | - |
restore | 备份恢复角色 | - | - |
readAnyDatabase | 所有数据库角色 | 赋予用户所有数据库的读权限,只在admin数据库中可用 | - |
readWriteAnyDatabase | 所有数据库角色 | 赋予用户所有数据库的读写权限,只在admin数据库中可用 | - |
userAdminAnyDatabase | 所有数据库角色 | 赋予用户所有数据库管理User的权限,只在admin数据库中可用 | - |
dbAdminAnyDatabase | 所有数据库角色 | 赋予管理所有数据库的权限,只在admin数据库中可用 | - |
root | 超级账号 | 超级权限,只在admin数据库中可用 | - |
clusterAdmin | 集群管理角色 | 赋予管理集群的最高权限,只在admin数据库中可用 | - |
clusterManager | 集群管理角色 | 赋予管理和监控集群的权限 | - |
clusterMonitor | 集群管理角色 | 赋予监控集群的权限,对监控工具具有readonly的权限 | - |
hostManager | 集群管理角色 | 赋予管理Server | - |
connections
//.查看当前DB的连接的主机地址
db.getMongo()
#.输出所有连接
echo "db.currentOp(true).inprog;" | /opt/mongodb/bin/mongosh -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin --host 127.0.0.1 --port 3717 admin | grep "client:"
//.查看总的连接数
db.serverStatus().connections;
//.查看当前所有的连接详情
db.currentOp();
db.currentOp(true).inprog;
//.杀掉某个具体的进程
db.killOp(<number>);
索引与调优
索引的创建与删除
//.准备测试数据
use db1;
db.aaa.drop();
db.aaa.insertMany([{name:'sam',qty:25,insert_time:new Date()},{name:'joy',qty:40,insert_time:new Date()}]);
db.aaa.find();
//.查看索引
db.aaa.getIndexes();
//.根据查询条件查看执行计划
db.aaa.find({name:"sam"}).explain();
//.创建索引
db.aaa.ensureIndex({"name":1}, {"background":true}); //.单列索引,1为升序,-1为降序,后台执行
db.aaa.ensureIndex({"qty":-1}, {"unique":true}); //.唯一索引
db.aaa.ensureIndex({"name":1, "qty":-1}); //.组合索引
db.aaa.ensureIndex({"name":-1}, {"name":"aaa_id","background":true});
//.唯一索引也支持组合索引
db.members.createIndex({lastname:1, firstname:1}, {unique:true})
//.创建嵌入式的索引
db.aaa.drop();
db.aaa.insertOne({name:"sam", location:{state:"NY", city:"New York"}, "age":18});
db.aaa.find({"location.state":"NY"});
db.city.ensureIndex({"location.state":1});
//.时效性数据推荐使用TTL(Time to Live)索引,对一个date类型的单列配置过期属性(时间戳或clock则不行)可实现对文档的自动过期删除
db.aaa.createIndex({"insert_time":1}, {expireAfterSeconds:60*60*24*7});
//.重建索引,该操作会删除表上的所有索引(包含_id)并重建所有索引
db.aaa.reIndex();
//.根据name删除指定索引
db.aaa.dropIndex("name_1");
//.删除所有索引
db.aaa.dropIndexes();
压缩库表
//.使用compact压缩单个集合或索引(注:compact操作是不会释放磁盘空间的,而是把释放的空间继续给mongodb使用)
use db1;
db.aaa.storageSize(); //.记录一下压缩前的大小
db.aaa.runCommand('compact'); //.压缩方式1
db.runCommand({compact : 'aaa' }); //.压缩方式2
db.aaa.storageSize(); //.记录一下压缩后的大小
附录
兼容性更改
已删除的命令 | 受影响的版本 | 替代方案 |
---|---|---|
db.collection.save() | MongoDB 5.0 | db.collection.insertOne() db.collection.insertMany() |
db.collection.copyTo() | MongoDB 5.0 | $out |
db.collection.ensureIndex() | MongoDB 5.0 | db.collection.createIndex() |
db.copyDatabase('db1','db1_bak') | MongoDB 4.0 | - |
db.collection.count() | MongoDB 5.0 | - |
db.collection.update() | - | - |