mongodb入门篇

基本操作

登入与登出

#.登陆测试
/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

#.非交互式
/opt/mongodb/bin/mongosh -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin --host 127.0.0.1 --port 3717 admin --quiet --eval "db.version()"

#.删除 db1库.aaa表
/opt/mongodb/bin/mongosh -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin --host 127.0.0.1 --port 3717 admin --quiet --eval "db.getSiblingDB('db1').aaa.drop()"
/opt/mongodb/bin/mongosh -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin --host 192.168.31.101 --port 3717 admin --quiet --eval "db.getSiblingDB('db1').getCollectionNames()"

实例的管理

  • 根据 db.serverStatus() 可以查看服务器状态状态
//.可作为心跳检测
db.runCommand({ping:1})

//.查看版本
db.version();

//.查看 serverStatus() 所返回的大类
print(Object.keys(db.serverStatus()))

//.查看存储引擎
db.serverStatus().storageEngine.name;

//.查看连接数信息
db.serverStatus().connections;

//.查看详细指标
db.serverStatus().connections.current;         //.当前连接数
db.serverStatus().connections.available;       //.可用连接数
db.serverStatus().connections.totalCreated;    //.历史总创建数

//.网络
db.serverStatus().network.bytesIn;
db.serverStatus().network.bytesOut;

//.操作计数器
db.serverStatus().opcounters.insert;
db.serverStatus().opcounters.query;
db.serverStatus().opcounters.update;
db.serverStatus().opcounters.delete;
db.serverStatus().opcounters.command;

//.缓存命中率: 1 - (wiredTiger.cache['pages read into cache'] / wiredTiger.cache['pages requested from the cache'])
//.低于 95% 可能意味着内存不足或工作集太大
db.serverStatus().wiredTiger.cache['pages read into cache'];
db.serverStatus().wiredTiger.cache['pages requested from the cache'];

//.查看启动参数
db.serverCmdLineOpts()
db.adminCommand({getCmdLineOpts:1})

//.检查是否企业版,是否启用认证,是否配置密码策略
var bi=db.adminCommand({buildInfo:1});
var gc=db.adminCommand({getCmdLineOpts:1});
var ee=!!bi.enterpriseModule;
var pa=gc.parsed.auth||(gc.parsed.security&&gc.parsed.security.authorization);
var pp=ee?!!db.getSiblingDB("admin").system.passwordPolicy.findOne():null;
print("enterprise:"+ee+",auth:"+pa+",password_policy:"+pp)

// 获取所有运行时参数
db.adminCommand({getParameter: '*'})

// 获取特定参数
db.adminCommand({getParameter: 1, "quiet": 1}) 

//.主机系统信息, 但不包括磁盘使用情况
db.hostInfo().system.memSizeMB       // 总物理内存 (MB)
db.hostInfo().system.numCores        // CPU核心数
db.hostInfo().system.cpuArch         // CPU架构 (x86_64, arm64等)
db.hostInfo().system.numaEnabled     // NUMA是否启用
db.hostInfo().os.name                // 操作系统的发行版名称 (Ubuntu, CentOS, macOS)
db.hostInfo().os.version             // 操作系统的内核/系统版本

//.查看内存指标
db.serverStatus().mem
db.serverStatus().mem.resident      // 常驻内存大小 (MB),即实际使用的物理内存

//.mongo实际使用的物理内存、wiredTiger配置的内存、物理内存、mongo内存使用率、wiredTiger配置的内存占比率
var actual_use_mem_mb = db.serverStatus().mem.resident;
var total_system_mem_mb = db.hostInfo().system.memSizeMB;
var wiredTiger_config_size_mb = (db.serverStatus().wiredTiger.cache["maximum bytes configured"]/1024/1024).toFixed(0);
var mongo_mem_usage_percent = (actual_use_mem_mb / total_system_mem_mb * 100).toFixed(2);
var wiredTiger_mem_config_percent = (wiredTiger_config_size_mb / total_system_mem_mb * 100).toFixed(2);
print(actual_use_mem_mb + ',' + wiredTiger_config_size_mb + ',' + total_system_mem_mb + ',' + mongo_mem_usage_percent + ',' + wiredTiger_mem_config_percent)

//.提供操作系统级别的额外信息,主要用于诊断和监控Mongo与操作系统的交互
db.serverStatus().extra_info
  • 调用外部脚本
//.测试方法1
echo 'printjson( db.version() );' > test1.sql
conn_str="--host 127.0.0.1 --port 3717"
command="db.runCommand({ping:1})"

mongosh $conn_str --quiet --file test1.sql
mongosh $conn_str --quiet --eval "show dbs;"
mongosh $conn_str --quiet --eval "JSON.stringify($command)"

//.测试方法2
echo 'db = connect( "localhost:3717/admin" );' > test2.js
echo 'printjson( db.version() );' >> test2.js
mongosh --file test2.js

数据库的管理

//.创建数据库,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)});

//.查看所有数据库的大小, 统一单位MB
const dbs = db.adminCommand({listDatabases:1}).databases;
dbs.forEach(d => { print(d.name + ', ' + (d.sizeOnDisk/1024/1024).toFixed(2) + ' MB'); });

//.查看所有数据库的大小
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为单位的库大小, 注意 dataSize 代表实际存储的数据总大小(未压缩)
db.stats(1048576);          //.以MB为单位的库大小, 注意 storageSize 代表在磁盘上实际占用的空间大小
db.stats(1073741824);       //.以GB为单位的库大小

//.查看当前库所有表的行数及大小
db.getCollectionNames().forEach(c => {
  const stats = db[c].stats();
  print(`${c}: 行数=${(stats.count)}, 数据=${(stats.size/1024/1024).toFixed(2)}MB, 存储=${(stats.storageSize/1024/1024).toFixed(2)}MB, 碎片率=${(stats.storageSize/stats.size).toFixed(2)}`);
});

//.获取所有数据库的表的大小(排除系统数据库), 返回格式: 库名,表名,行数,数据大小(单位MB),存储大小(单位MB),碎片率
var dbs = db.adminCommand('listDatabases').databases;
dbs.forEach(dbInfo => {
  var dbName = dbInfo.name;
  if (dbName === 'admin' || dbName === 'local' || dbName === 'config') { return; }
  var targetDb = db.getSiblingDB(dbName);
  var collections = targetDb.getCollectionNames();
  collections.forEach(collection => {
    const stats = targetDb[collection].stats();
    print(`库名=${dbName},表名=${collection},行数=${stats.count},数据大小=${(stats.size/1024/1024).toFixed(2)},存储大小=${(stats.storageSize/1024/1024).toFixed(2)},碎片率=${(stats.storageSize/stats.size).toFixed(2)}`);
  });
});

//.查看表名与文件名的对应关系(uri对应的就是该表对应的文件名)
db.aaa.stats();

//.查看指定表的行数及大小
db.aaa.count();                                 // 查看行数
(db.aaa.dataSize()/1024/1024).toFixed(2)        // 仅查看数据大小,单位MB
(db.aaa.totalIndexSize()/1024/1024).toFixed(2)  // 仅查看索引大小,单位MB
(db.aaa.totalSize()/1024/1024).toFixed(2)       // 查看存储大小(数据+索引,压缩后)
(db.aaa.storageSize()/1024/1024).toFixed(2)     // 查看磁盘上实际占用的空间(含索引)

//.查看指定表的行数及大小及膨胀率
var stats = db.aaa.stats();
var ratio = stats.storageSize / stats.size;
print("行数: " + stats.count + " | 存储: " + (stats.storageSize/1024/1024).toFixed(2) + "MB | 数据: " + (stats.size/1024/1024).toFixed(2) + "MB | 索引: " + (stats.totalIndexSize/1024/1024).toFixed(2) + "MB | 膨胀率: " + ratio.toFixed(2));

//.备份数据表(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);});

//.把aaa表中 < 20240901 的数据复制到bbb表中
//.对于大数据量 $out 比 insertMany 效率高很多,原子操作(要么全部成功要么全部失败),完全替换而非追加,目的表不会继承索引
use db1;
db.aaa.deleteMany({});
db.aaa.insertMany([{entry:"test_2023",InsertTime: new Date("2023-07-01T11:20:00"),content:"要删除"}, {entry:"test_2024",InsertTime: new Date("2024-09-02T08:00:00"),content:"要保留"}]);
var cutoffDate = new Date("2024-09-01T00:00:00");
db.aaa.aggregate([ {$match:{InsertTime:{$lt:cutoffDate}}}, {$out:"bbb"} ]);

//.修改表名-方式1
use db1;
db.aaa.renameCollection("bbb");

//.修改表名-方式2(使用renameCollection会迁移数据+索引)
use admin;
db.runCommand({'renameCollection':'db1.bbb','to':'db1.aaa'});

//.清空全表
db.aaa.deleteMany({});

//.删除数据表
db.aaa.drop();
db.getCollection("tmpCJWjw.renameCollection").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({});

角色的管理

createRole

  • 创建自定义角色(示例 healthChecker,用于mongodb巡检的最小权限)
//.创建自定义角色(示例 healthChecker,用于mongodb巡检的最小权限)
db.createRole({
  role: "healthChecker",
  privileges: [
    {
      resource: { cluster: true },
      actions: [
        "serverStatus",        // 服务器状态
        "top",                 // 操作统计
        "connPoolStats",       // 连接池统计
        "getCmdLineOpts",      // 启动参数
        "hostInfo",            // 主机信息
        "inprog",              // 当前操作
        "listDatabases",       // 数据库列表
        "replSetGetStatus",    // 副本集状态
        "replSetGetConfig",    // 副本集配置
        "getParameter",        // 参数获取
        "getShardMap",         // 分片映射
        "listShards",          // 分片列表
      ]
    },
    {
      resource: { db: "", collection: "" },
      actions: [
        "collStats",        // 集合统计
        "dbStats",          // 数据库统计
        "indexStats",       // 索引统计
        "listCollections",  // 集合列表
        "listIndexes"       // 索引列表
      ]
    }
  ],
  roles: []
});

//.基于自定义角色(示例 healthChecker)创建账号(示例 test01)
db.createUser({
  user: "test01",
  pwd: "Admin_147",
  roles: ["healthChecker"]
});

//.基于默认角色(示例 readAnyDatabase)创建账号(示例 test02)
db.createUser({user:"test02",pwd:"Admin_147",roles:[{role:"readAnyDatabase", db:"admin"}]});

//.查看所有自定义的角色信息
db.getRoles()

//.查看所有的角色信息
db.runCommand({rolesInfo:1,showBuiltinRoles:true})
db.runCommand({rolesInfo:1,showBuiltinRoles:true}).roles.forEach(r => print(r.role))

grantPrivilegesToRole

  • 针对已经创建的角色,可以通过 grantPrivilegesToRole 为用户定义的角色分配特权
//.创建自定义角色,resource 针对 cluster
db.createRole({role:"healthChecker",privileges:[{resource:{cluster:true},actions:["serverStatus","top"]}],roles:[]});

//.针对自定义角色,添加新的角色,resource 针对 db
db.grantPrivilegesToRole("healthChecker",[{resource:{db:"",collection:""},actions:["dbStats","listIndexes"]}]);
  • 利用 showPrivileges 查看账号的角色信息
db.runCommand({usersInfo:"dba_check",showPrivileges:true});
db.getUser("dba_check")

dropRole

//.删除角色
db.dropRole("healthChecker");

账号的管理

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\mongodb\bin
.\mongo.exe --authenticationDatabase admin -u dba_admin -p cf_rB1NKCzbaQuPH

cd /d d:\sqldata\mongodb\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 -
  • 查看高权限账号
// 必须切换到 admin 库查看
use admin;
db.system.users.find({"roles.role":{$in:["root","dbOwner","clusterAdmin"]}}).pretty()
db.system.users.find({"roles.role":{$in:["root","dbOwner","clusterAdmin"]}},{_id:1,roles:1}).pretty()

// 必须切换到 admin 库查看
db.system.users.find(
  {"roles.role": {$in: ["root","dbOwner","clusterAdmin","userAdminAnyDatabase","dbAdminAnyDatabase"]}}
).forEach(function(user) {
  var highrole = [];
  user.roles.forEach(function(role) {
    if (["root","dbOwner","clusterAdmin","userAdminAnyDatabase","dbAdminAnyDatabase"].includes(role.role)) {
        highrole.push(role.role + "," + role.db);
    }
  });
  if (highrole.length > 0) {
    print(user.user + "," + user.db + "," + highrole.join(", "));
  }
});

// 可以在任意库查看
var users = db.getSiblingDB("admin").runCommand({usersInfo:1});
if (users && users.ok === 1 && users.users) {
  var highPrivUsers = users.users.filter(function(user) {
    return (user.roles || []).some(function(role) {
      return ["root","dbOwner","clusterAdmin","userAdminAnyDatabase","dbAdminAnyDatabase"].includes(role.role) || 
        (role.db === "admin" && ["root","dbOwner","clusterAdmin","userAdminAnyDatabase","dbAdminAnyDatabase"].includes(role.role));
    });
  });

  highPrivUsers.forEach(function(user) {
    var roleInfo = (user.roles || []).map(function(role) { return role.role + "," + (role.db || "admin"); }).join("; ");
    print(user.user + "," + user.db + "," + roleInfo);
  });
};

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();

//.创建索引
//.实测: 一张大表26337252行、dataSize共122G、totalSize共148G,针对时间字段添加索引耗时 1133 秒
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});

//.使用 collMod 修改 expireAfterSeconds 属性
db.runCommand({collMod: "aaa", index: { keyPattern: { insert_time: 1 }, expireAfterSeconds: 60}});

//.重建索引,该操作会删除表上的所有索引(包含_id)并重建所有索引
db.aaa.reIndex();

//.根据name删除指定索引
db.aaa.dropIndex("name_1");

//.当前库所有表的索引个数
db.getCollectionNames().forEach(tabs => print(tabs + "," + db[tabs].getIndexes().length))

//.所有库所有表的索引个数
var dbs = db.adminCommand('listDatabases').databases;
dbs.forEach(dbInfo => {
  var dbName = dbInfo.name;
  if (dbName === 'admin' || dbName === 'local' || dbName === 'config') { return; }
  var targetDb = db.getSiblingDB(dbName);
  var collections = targetDb.getCollectionNames();
  collections.forEach(collection => {
    const stats = targetDb[collection].getIndexes();
    if (stats.length >= 1) { 
      print(`${dbName},${collection},${stats.length}`);
    }
  });
});

//.删除所有索引
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() - -
Copyright © www.sqlfans.cn 2021 - 2026 All Right Reserved更新时间: 2026-09-05 09:23:20

results matching ""

    No results matching ""