之前写过几篇有关MongoDB的文章,主要是记录一些当时碰到的问题和解决思路。本篇文章主要记录一些MongoDB的常用命令和查询语句。以便不用每次用到了再去搜百度(有时候能不能搜到还要看运气)。
创建MongoDB用户和密码
很多朋友创建了MongoDB以后就裸奔,这是万万使不得的。当我们第一次启动MongoDB的时候是没有用户名密码的,因此可以直接启动(参考MongoDB手册)。命令如下:
./bin/mongod --port 27017 --bind_ip 0.0.0.0 --fork --dbpath /data/db --logpath /data/logs/mongod.log --logappend
创建读写用户权限
接下来我们登陆MongoDB以后(默认是以管理员权限登陆的),分别创建三个用户。以下为登陆新建的MongoDB:
mongo --port 27017
#1. 创建管理员用户
首先我们要选择要操作的数据库。创建用户的话,统一在admin中创建。另外在创建用户的过程中,需要指定该用户的权限和对应该权限的数据库。以下是创建管理员账户,所以对应的权限是root,对应的数据库是admin。
use admin; db.createUser( { user: "mongo_root", pwd: "Admin$2020", roles: [ { role: "root", db: "admin" }], passwordDigestor: "server" } )
#2. 创建读写权限用户
接下来我们为我们业务相关的数据库创建一个读写用户,用户名为readwrite-user,密码为ReadWrite$2020,权限为读写,对应的数据库名称为mybank。
use mybank; db.createUser( { user: "readwrite-user", pwd: "ReadWrite$2020", roles: [{role: "readWrite", db: "mybank"}] })
#3. 创建只读权限用户
随后,我们为我们业务相关的数据库创建一个只读用户,用户名为readeronly-user,密码为ReadOnly$2020,权限为只读,对应的数据库名称为mybank。
use mybank; db.createUser( { user: "readeronly-user", pwd: "ReadOnly$2020", roles: [{role: "read", db: "mybank"}] })
#4. 删除用户
如果创建用户错误,我们可以删除用户并重新创建。注意删除用户,需要至少userAdminAnyDatabase用户登陆并操作:
use admin; db.system.users.remove({user:"readeronly-user"}) # 查看用户列表 db.system.users.find()
开启MongoDB身份认证
用户创建好以后,我们需要重启MongoDB并且开启身份认证。
db.adminCommand( { shutdown: 1 } ) ./bin/mongod --auth --port 27017 --bind_ip 0.0.0.0 --fork --dbpath /data/db --logpath /data/logs/mongod.log --logappend
使用用户名密码连接MongoDB
开启了身份认证以后,我们可以分别用三个不同的账号登陆到MongoDB数据库中:
./mongo 127.0.0.1:27017 -u "mongo_root" -p "Admin$2020" --authenticationDatabase "admin" ./mongo 127.0.0.1:27017 -u "readwrite-user" -p "ReadWrite$2020" --authenticationDatabase "mybank" ./mongo 127.0.0.1:27017 -u "readeronly-user" -p "ReadOnly$2020" --authenticationDatabase "mybank"
查看MongoDB数据库和Collection的状态
查看MongoDB数据库,或者数据库中的Collection的状态,使用的命令是不一样的。
查看MongoDB数据库状态
我们可以使用以下命令查看MongoDB数据库mybank状态:
use mybank; db.stats();
返回的结果为:
{
“db” : “mybank”,//当前数据库
“collections” : 23,//当前数据库多少表
“views” : 0,
“objects” : 2164, //当前数据库所有表多少条数据
“avgObjSize” : 5579.812384473198, //每条数据的平均大小
“dataSize” : 12074714, //所有数据的总大小
“storageSize” : 9441280, //所有数据占的磁盘大小
“numExtents” : 0,
“indexes” : 23, //索引数
“indexSize” : 765952, //索引大小
“fsUsedSize” : 5157105664,
“fsTotalSize” : 85222670336,
“ok” : 1
}
查看MongoDB数据库中Collection状态
我们可以使用以下命令查看数据库中Collection状态:
db.getCollection('user-account').stats()
由于这个信息量比较大,我们就不贴样例数据了。
备份和恢复MongoDB数据库
我们可以一条命令备份或者恢复整个MongoDB中所有的数据库和Collection,也可以分库分表备份。
整库备份MongoDB
./mongodump --username mongo_root --password "Admin$2020" --authenticationDatabase "admin" --out backup
整库恢复MongoDB
./mongorestore --username mongo_root --password "Admin$2020" --authenticationDatabase "admin" --dir backup
分库分表备份MongoDB
./mongodump --username mongo_root --password "Admin$2020" --authenticationDatabase "admin" --collection user-account --db mybank --out backup
分库分表恢复MongoDB
./mongorestore --username mongo_root --password "Admin$2020" --authenticationDatabase "admin" --db mybank --collection user-account /backup/mybank/user-account.bson
在MongoDB中使用Aggregate聚合
以下代码是在mybank的名为user的Collection中,寻找存在age(年龄)字段的用户,并且统计不同age中用户数量。
db.getCollection("user").aggregate([ {$match: {age: { $exists: true }}}, {$project: {'age':1}}, {$sort: {create_date: -1}}, {$group: {"_id": "$age",sum: {$sum: 1}}} ])
Aggregate案例#2
以下代码是在名为news的Collection中,寻找在2020年1月份中,网易新闻标题与“冠状病毒”相关的新闻。
var fromDate = new Date('2020-01-01 00:00:00'); var fromDateInt = fromDate.getTime()/1000; var toDate = new Date('2020-02-01 00:00:00'); var toDateInt = toDate.getTime()/1000; db.news.aggregate([ {$match: {_id: { $gt: ObjectId(fromDateInt), $lt: ObjectId(toDateInt) }}}, {$sort: {_id: 1}}, {$match: {"url": {$regex: "163.com"}} {$match: {"news_title": {$regex: "冠状病毒"}} ])
Aggregate案例#3
在aggregate中使用hint,能够强制aggregate语句使用指定的索引,能够有效的提升查询速度。之前在《单台MongoDB服务器的不可承受之重》中详细说明了Mongodb使用索引的情况。
var fromDate = new Date('2020-01-01 00:00:00'); var fromDateInt = fromDate.getTime()/1000; var toDate = new Date('2020-02-01 00:00:00'); var toDateInt = toDate.getTime()/1000; db.news.aggregate([ {$match: {_id: { $gt: ObjectId(fromDateInt), $lt: ObjectId(toDateInt) }, site_id:8898}}, {$sort: {_id: 1}}, {$match: {"url": {$regex: "163.com"}} {$match: {"news_title": {$regex: "冠状病毒"}} ], {hint: {_id:-1, site_id:1}})
上段代码中使用_id和site_id两个索引字段进行检索,大大提高查询速度。
在MongoDB中使用MapReduce
以下是使用MapReduce的一个案例,也是在名为user的Collection中,寻找存在age(年龄)字段的用户,并且统计不同age中用户数量,最后把结果存到名为result的Collection中。
db.getCollection("user").mapReduce( function() { emit(this.age, 1); }, function(key, values) {return Array.sum(values)}, { query:{age: { $exists: true }}, out:"result" //save to result collection } )
另外,在Google中搜到一篇不错的文章(其实没有细看),也可以参考:MongoDB中使用MapReduce来进行聚合操作。另外,在MongoDB手册中也有大量关于MapReduce使用案例。
MapReduce案例#2
统计url是否重复,存到result里面去:
db.getCollection("website").mapReduce( function() { emit(this.url, 1); }, function(key, values) {return Array.sum(values)}, { query:{url: { $exists: true }}, out:"result" //save to temp collection } )
MongoDB中常用搜素
以下是一些常用的搜索方法,比较简单就不解释了,大家可以自己看。
db.getCollection("news").find({source:{$regex: "163.com"}}).count(); db.getCollection("news").find({source:{$regex: "163.com"}}).projection({_id:1, url:1, title:1}).sort({_id:1}).skip(10).limit(10); db.getCollection("news").find({source:"https://news.163.com", create_date:{$lt:ISODate("2020-01-10T16:00:00.000Z")}}).count() db.getCollection("news").remove({source:"https://news.163.com", create_date:{$gte:ISODate("2019-05-06T16:00:00.000Z")}})
在MongoDB中可以定义函数
以下是定义一个搜索Collection的函数,如果Collection名字中包含user就打印出来。
function searchTable(tableName) { db.getCollectionNames().forEach(function(collection) { // find the last item in a collection if(collection.indexOf(tableName) != -1) { print(collection) } }) } searchTable("user")
扫码联系船长