本文已参与「新人创作礼」活动,一起开启掘金创作之路。
MongoDB是一个开源文档数据库,提供高性能、高可用性和自动伸缩。
术语和概念
| SQL | MongoDB |
|---|
| database | database |
| table | collection |
| row | document or BSON document |
| column | field |
| index | index |
| table joins | $lookup, embedded documents |
| primary key(Specify any unique column or column combination as primary key) | primary key(In MongoDB, the primary key is automatically set to the _id field) |
| aggregation (e.g. group by) | aggregation pipeline(See the SQL to Aggregation Mapping Chart) |
安装
$ curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.6.3.tgz
$ tar -zxvf mongodb-linux-x86_64-3.6.3.tgz
$ cp -R -n mongodb-linux-x86_64-3.6.3/ mongodb
$ vim ~/.bash_profile
export PATH=<mongodb-install-directory>/bin:$PATH
运行
# mongod进程保存数据目录,默认/data/db,可通过dbpath指定
$ mkdir -p /data/db
# 运行MongoDB --config:指定服务启动配置文件;--auth:开启认证;--dbpath:mongod进程保存数据目录
$ mongod --config /etc/mongod.conf --auth
# 使用MongoDB
$ mongo --host 127.0.0.1 --port 27017 uhe_commission -u uhetrip -p uhetrip
$ mongo 127.0.0.1:27017/uhe_commission -u uhetrip -p uhetrip
/etc/mongod.conf
systemLog:
destination: file
path: "/var/log/mongodb/mongod.log"
logAppend: true
storage:
dbPath: "/data/db"
journal:
enabled: true
processManagement:
fork: true
pidFilePath: "/data/software/mongodb-linux-x86_64-3.6.3/mongo.pid"
net:
bindIp: 0.0.0.0
port: 27017
setParameter:
enableLocalhostAuthBypass: false
Linux包初始化脚本包含了MongoDB官方包依赖的特定值systemLog.path, storage.dbPath, and processManagement.fork。如果在默认配置文件中修改这些设置,mongod可能不会启动。
| key | value | Default | 说明 |
|---|
| systemLog.destination | file|syslog | | MongoDB发送所有日志输出的目的地,如指定file,必须同时指定systemLog.path值 |
| systemLog.path | "/var/log/mongodb/mongod.log" | | mongod或mongos应该发送所有诊断日志信息的日志文件的路径 |
| systemLog.logAppend | true|false | False | 当mongod或mongos重启实例时,true-新的日志添加到现有日志文件的末尾,false-将备份现有日志并创建一个新文件 |
| storage.dbPath | "/data/db" | "/data/db" | mongod实例存储数据的目录 |
| storage.journal.enabled | true|false | "/data/db" | 启用和禁用持久性日志以确保数据文件仍然有效和可恢复。同storage.dbPath一起使用 |
| processManagement.fork | true|false | false | 后台运行mongos或mongod的守护进程模式 |
| processManagement.pidFilePath | "/data/mongod.pid" | | 指定一个文件位置来保存mongos或mongod进程的进程ID |
| processManagement.timeZoneInfo | "/usr/share/zoneinfo" | "/usr/share/zoneinfo" | 加载时区数据库的完整路径 |
| net.port | 27017 | 27017 | MongoDB实例监听的客户端连接TCP端口 |
| net.bindIp | 0.0.0.0,:: | localhost | To bind to all IPv4 and IPv6 addresses |
| net.maxIncomingConnections | 65536 | 65536 | mongos或mongod将接受的最大同时连接数 |
| net.wireObjectCheck | true|false | true | mongos或mongod实例会检查客户所有请求,组织无效的BSON插入到MongoDB数据库中 |
| setParameter.enableLocalhostAuthBypass | 0|false | true | 启用避开本地认证 |
用户、角色、认证
创建用户
> db.createUser(
{
user: "root",
pwd: "root",
roles: [ "root" ]
}
)
> db.createUser(
{
user: "admin",
pwd: "admin",
roles: [{role: "userAdminAnyDatabase", db: "admin"}]
}
)
> db.createUser(
{
user: "uhetrip",
pwd: "uhetrip",
roles:
[{role: "readWrite", db: "uhe_commission"},{role: "dbOwner", db: "uhe_commission"}]
}
)
内置的角色
| role | 说明 |
|---|
| -Database User Roles- | 数据库用户角色:针对每一个数据库进行控制 |
| read | 允许用户读取指定数据库所有非系统集合,以及系统集合中的system.indexes, system.js, system.namespaces |
| readWrite | 包含了所有read权限,以及修改所有非系统集合的和系统集合中的system.js的权限 |
| -Database Administration Roles- | 数据库管理角色:每一个数据库包含了下面的数据库管理角色 |
| dbAdmin | 一些数据库对象的管理操作(如索引创建、删除,查看统计或访问system.profile),但是没有数据库的读写权限 |
| userAdmin | 为当前用户创建、修改用户和角色。拥有userAdmin权限的用户可以将该数据库的任意权限赋予任意的用户 |
| dbOwner | 该数据库的所有者,具有该数据库的全部权限 |
| -Cluster Administration Roles- | 集群管理权限:admin数据库包含了下面的角色,用户管理整个系统,而非单个数据库。这些权限包含了复制集和共享集群的管理函数 |
| clusterAdmin | 提供了最大的集群管理功能。相当于clusterManager, clusterMonitor, and hostManager和dropDatabase的权限组合 |
| clusterManager | 提供了集群和复制集管理和监控操作。拥有该权限的用户可以操作config和local数据库(即分片和复制功能) |
| clusterMonitor | 仅仅监控集群和复制集 |
| hostManager | 提供了监控和管理服务器的权限,包括shutdown节点,logrotate, repairDatabase等 |
| -All-Database Roles- | 所有数据库角色:admin数据库提供了一个mongod实例中所有数据库的权限角色 |
| readAnyDatabase | 具有read每一个数据库权限。但是不包括应用到集群中的数据库 |
| readWriteAnyDatabase | 具有readWrite每一个数据库权限。但是不包括应用到集群中的数据库 |
| userAdminAnyDatabase | 具有userAdmin每一个数据库权限,但是不包括应用到集群中的数据库 |
| dbAdminAnyDatabase | 提供了dbAdmin每一个数据库权限,但是不包括应用到集群中的数据库 |
| -Superuser Roles- | 超级管理员权限: |
| root | 任何数据库上执行任何操作 |
| -Backup and Restoration Roles- | 备份恢复角色: |
| backup | |
| restore | |
The mongo shell
# 关机
> use admin;
> db.shutdownServer();
# 切换数据库
> use myNewDatabase
# 修改密码
> db.updateUser( "admin",{pwd:"password"});
# 插入数据
> db.myCollection.insertOne( { x: 1 } );
# 格式化输出结果
> db.myCollection.find().pretty();
# 查询条件 $gt(大于); $gte(大于等于); $lt(小于); $lte(小于等于); $ne(不等);
> db.COLLECTION_NAME.find({"age":{$gt:22}})
# 查询条件 $or(或); $in(包含); $nin(排除);
> db.user.find({$or:[{"name":"lihp"},{"name":"tom"}]})
> db.user.find({"address.province":{$in{"hebei","beijing"}}})
# 按ID查询
> db.COLLECTION_NAME.find({ "_id" : ObjectId("55f1b696980f8e29fa26b2b5")})
# 排序 1=升序 -1=降序
> db.COLLECTION_NAME.find().sort({"key":1})
# 时间查询
> db.basestr.find({"expiryTime":{$lte:ISODate("2016-08-16 23:59:59")}}).count()
# 只显示expiryTime字段。1-显示;0-不显示
> db.basestr.find({"expiryTime":{$lte:ISODate("2016-08-16 23:59:59")}},{expiryTime:1}).count()
# 查询指定长度的数组
> db.food.find({“fruit”:{$size:3}})
# 返回数组中的子集. 2:查询前两条数据; -2:查询后两条数据
> db.food.find({“fruit”:{$slice:2}})
索引
> for (var i=1; i<=100001; i++ ) db.test_4.save({skyid:i,name:'a'});
> db.test_4.find().limit (5);
> db.test_4.createIndex({key:1},{"name":"idx_basestr_key","unique":true})
> db.test_4.dropIndex('idx_test_4_skyid');
> db.test_4.getIndexes();
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "enginedb.test_4"
}
]
> db.test_4.find().explain();
Mongo连接池
| key | 说明 |
|---|
| connectionsPerHost | 每个主机最大允许的连接数 |
| threadsAllowedToBlockForConnectionMultiplier | 线程队列数,它以上面connectionsPerHost值相乘的结果就是线程队列最大值。如果连接线程排满了队列就会抛出“Out of semaphores to get db”错误 |
| maxWaitTime | 最大等待连接的线程阻塞时间 |
| connectTimeout | 连接超时的毫秒。0是默认和无限 |
| socketTimeout | socket超时。0是默认和无限 |
| autoConnectRetry | 这个控制是否在一个连接时,系统会自动重试 |
| maxConnectionIdleTime | 最大空闲时间 |
| maxConnectionLifeTime | 最大存活时间 |
Mongo 命令
db.getCollection('policy').aggregate(
[
{$match: {"supplierId" : "681"}},
{$group: {_id : {"$status","$verifyType"},number : {$sum : 1}}},
{$sort: {_id : -1 }}
]
)
db.getCollection('policy').group({
condition:{"supplierId":"681"},
key: { 'status':1,'verifyType':1},
initial : {"total":0},
reduce : function Reduce(doc, out) {
out.total+=1
}
});
db.test.find({"check":{$exists:true}});
db.test.find({"check":{$ne:null}});
db.test.find({"check":null})
db.getCollection('policy').find({"supplierId":"681"},{"policyId":1,"status":1,"verifyType":1})
db.getCollection('policy').find({"supplierId":"681","status":"T"}).forEach(function(item){db.getCollection('policy').update({"_id":item._id},{$set:{"verifyType" : 2}})})
db.getCollection('policy').update({查询器},{修改器},true,false)
{$set:{field: value}}
{$inc:{field: value}}
{$unset:{field: 1}}
{$push:{field: value}}
{$pushAll:{database:["Oracle","MySQL"]}
{$set:{array.$.field:value}}
Example:
db.sample.update({"database.type":"MongoDB"},{$set:{"database.$.author":"Mongo"}})
参考
- SQL to MongoDB Mapping Chart(create,alert,select,insert,update,delete)
- SQL to Aggregation Mapping Chart(groupby,having,orderby,sum,count...)
- Install MongoDB Community Edition From Tarball
- Configuration File Options
- Built-In Roles
- mongo Shell Methods
- Mongodb中Aggregation特性
- MongoDB聚合操作
- mongoDB 按照时间字段分组 【24小时,周,月,年】