介绍
简介
MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
MongoDB 是非关系型数据库当中功能最丰富,最像关系型数据库的。
随着大数据的不断发展,非关系型数据库已经变得越来越重要,相关的产品也都得到了飞速发展。而其中MongoDB更是佼佼者,作为高性能开源文档数据库,MongoDB以敏捷、可扩展和对企业应用友好而著称,因其操作简单、完全免费、源码公开等特点,受到了IT从业人员的青睐,并被广泛部署于实际的生产环境中。
mongo中文网
BSON
BSON是一种类似json的二进制形式的存储格式,简称Binary JSON,它和JSON一样,支持内嵌的文档对象和数组对象,但是BSON有JSON没有的一些数据类型,如Date和BinData类型。
BSON可以做为网络数据交换的一种存储形式,这个有点类似于Google的Protocol Buffer,但是BSON是一种schema-less的存储形式,它的优点是灵活性高,但它的缺点是空间利用率不是很理想。
BSON有三个特点:轻量性、可遍历性、高效性。
优点
它的特点是高性能、易部署、易使用,存储数据非常方便。主要功能特性有:
- 面向集合存储,易存储对象类型的数据。
- 模式自由。
- 支持动态查询。
- 支持完全索引,包含内部对象。
- 支持查询。
- 支持复制和故障恢复。
- 使用高效的二进制数据存储,包括大型对象(如视频等)。
- 自动处理碎片,以支持云计算层次的扩展性
- 支持RUBY,PYTHON,JAVA,C++,PHP等多种语言。
- 文件存储格式为BSON(一种JSON的扩展)
非关系型数据库与关系型数据库区别
非关系型数据库的优势:
性能
NOSQL是基于键值对的,可以想象成表中的主键和值的对应关系,而且不需要经过SQL层的解析,所以性能非常高。
可扩展性
同样也是因为基于键值对,数据之间没有耦合性,所以非常容易水平扩展。
关系型数据库的优势:
复杂查询
可以用SQL语句方便的在多个表之间做非常复杂的数据查询。
事务支持
使得对于安全性能很高的数据访问要求得以实现。
总结:
- 数据库功能是用来存储数据的。
- 数据库分为关系系数据库和非关系型数据库(nosql)
- 关系型数据库是由表和表之间的关系组成的,nosql是由集合组成的,集合下面是很多的文档。
- 非关系型数据库文件存储格式为BSON(一种JSON的扩展)。
数据类型
| 数据类型 |
描述 |
| String |
字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。 |
| Integer |
整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。 |
| Boolean |
存储一个布尔值,true或false。 |
| Double |
双精度浮点值。用于存储浮点值。 |
| Min/Max keys |
将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。 |
| Array |
用于将数组或列表或多个值存储为一个键。 |
| Timestamp |
时间戳。记录文档修改或添加的具体时间。 |
| Object |
用于嵌入式的文档,即一个值为一个文档。 |
| Null |
用于创建空值。 |
| Symbol |
符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。 |
| Date |
日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。表示当前距离 Unix新纪元(1970年1月1日)的毫秒数 |
| Object ID |
文档ID |
| Binary Data |
二进制数据。用于存储二进制数据。 |
| Code |
代码类型。用于在文档中存储 JavaScript 代码。 |
| Regular expression |
正则表达式类型。用于存储正则表达式。 |
ObjectId
ObjectId 类似唯一主键,可以很快的去生成和排序,包含 12 bytes,含义是:
- 前 4 个字节表示创建 unix 时间戳,格林尼治时间 UTC 时间,比北京时间晚了 8 个小时
- 接下来的 3 个字节是机器标识码
- 紧接的两个字节由进程 id 组成 PID
- 最后三个字节是随机数
MongoDB 中存储的文档必须有一个 _id 键。这个键的值可以是任何类型的,默认是个 ObjectId 对象
由于 ObjectId 中保存了创建的时间戳,所以你不需要为你的文档保存时间戳字段,你可以通过 getTimestamp 函数来获取文档的创建时间:

ObjectId
软件相关
命令
| 文件 |
描述 |
| mongo |
用于连接mogodb数据库服务器(管理器) |
| mongod |
用于开启服务器 |
| mongodump |
数据备份 |
| mongoexport |
数据导出 |
| mongoimport |
数据备份 |
| mongorestore |
数据还原 |
启动
| 参数 |
描述 |
| –bind_ip |
绑定服务IP,若绑定127.0.0.1,则只能本机访问,不指定默认本地所有IP |
| –logpath |
指定MongoDB日志文件,注意是指定文件不是目录 |
| –logappend |
使用追加的方式写日志 |
| –dbpath |
指定数据库数据存放路径 |
| –port |
指定服务器端口号,默认端口是27017 |
| –serviceName |
指定服务名称 |
| –serviceDisplayName |
指定服务名称,有多个mongodb服务时执行 |
| –install |
指定作为一个windows服务安装 |
1
| mongod --dbpath "d:\mongodb\db" --logpath "d:\mongodb\log\MongoDB.log"
|
保留数据库
| 数据库 |
描述 |
| admin |
从权限的角度来看,这是”root”数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。 |
| local |
这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合 |
| config |
当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。 |
数据库操作
语法
1 2 3 4 5 6 7 8 9 10 11 12 13
| show dbs;
db;
use dbname;
db.dropDatabase();
|
用户操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
use admin db.createUser({user:"admin",pwd:"admin12345",roles:["root"]}) db.createUser({user:"mhxy",pwd:"123456",roles:[{role:"dbOwner",db:"menpai"}]});
db.auth('admin','admin12345')
mongod --dbpath "d:\mongodb\db" --logpath "d:\mongodb\log\MongoDB.log" --serviceName "MongoDB" --auth
use admin db.system.users.find().pretty()
show users
db.dropUser(用户名)
db.dropAllUsers();
|
内置角色
| 系统 |
角色名 |
| 数据库用户角色 |
read、readWrite; |
| 数据库管理角色 |
dbAdmin、dbOwner、userAdmin; |
| 集群管理角色 |
clusterAdmin、clusterManager、clusterMonitor、hostManager; |
| 备份恢复角色 |
backup、restore; |
| 所有数据库角色 |
readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase |
| 超级用户角色 |
root |
| 内部角色 |
__system |
角色
| 角色 |
描述 |
| Read |
允许用户读取指定数据库 |
| readWrite |
允许用户读写指定数据库 |
| dbAdmin |
允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile |
| dbOwner |
dbOwner包含了readWrite,dbAdmin,userAdmin的权限 |
| userAdmin |
允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户 |
| clusterAdmin |
只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。 |
| readAnyDatabase |
只在admin数据库中可用,赋予用户所有数据库的读权限 |
| readWriteAnyDatabase |
只在admin数据库中可用,赋予用户所有数据库的读写权限 |
| userAdminAnyDatabase |
只在admin数据库中可用,赋予用户所有数据库的userAdmin权限 |
| dbAdminAnyDatabase |
只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。 |
| root |
只在admin数据库中可用。超级账号,超级权限 |
集合操作
语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
db.createCollection(name, options);
show collections;
db.集合名.drop();
db.集合名.ensureIndex({key1:1或-1, key2:1或-1...})
|
使用参考
1 2 3 4 5 6 7 8
| db.createCollection("stu")
db.createCollection("sub", { capped : true, size : 10 } )
db.menpai.ensureIndex({"score":1})
|
文档(数据)操作
语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
db.集合名.insert(数据)
db.集合名.remove({删除条件})
db.集合名.remove({})
db.集合名.find()
db.集合名.findOne()
db.集合名.find().pretty()
db.集合名.find({条件})
db.集合名.find({条件}).sort({"key1":1, "key2":-1, ...})
db.集合名.find().limit(num)
db.集合名.find().skip(num)
db.集合名.find().skip(num).limit(num)
db.集合名.find().count()
db.集合名.find().skip(num).limit(num).count(true)
db.集合名.find({"key1":/条件/})
db.集合名.update({条件}, {新数据});
db.集合名.update({条件}, {$set:{新数据}})
db.集合名.count()
|
查找条件
| 条件 |
描述 |
$gt |
大于 |
$lt |
小于 |
$gte |
大于等于 |
$lte |
小于等于 |
$ne |
不等于 |
$mod |
求余 |
$in |
在集合中 |
$nin |
不在集合中 |
$size |
值的个数,用于查询数组值 |
$exists |
是否存在某个键名 |
$or |
或者,多个条件满足一个就行了 |
$and |
和,多个条件满足都要满足才可以 |
$not |
在指定的表达式并查询到不匹配表达式的数据 |
使用参考
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| db.user.find({"school.0.teacher":1})
db.user.find({"baseinfo.age":1})
db.web.insert({"name":"ghost", "age":10})
db.users.remove({"name": "one"})
db.menpai.update({"num":1}, {"name":"大唐官府1"});
db.menpai.update({"num":2}, {$set:{"name":"方寸山2"}});
db.playerbaseinfo.find({"ctime":{$gt:1715788800000}}, { pid: 1, _id: 0 })
db.playertaskinfo.find({ "pid": { $in: [75006,75007,75008,75009,75010,75011,75012] } },{pid:1, taskInfo:2, _id:0})
|
聚合
聚合(aggregate)主要用于计算数据,类似sql中的sum()、avg()
语法
1 2 3 4
|
db.集合名称.aggregate([{管道1:{表达式}}, {管道2:{表达式}}])
|
常用管道
| 管道 |
描述 |
$group |
将集合中的文档分组,可用于统计结果 |
$match |
过滤数据,只输出符合条件的文档 |
$project |
修改输入文档的结构,如重命名、增加、删除字段、创建计算结果 |
$sort |
将输入文档排序后输出 |
$limit |
限制聚合管道返回的文档数 |
$skip |
跳过指定数量的文档,并返回余下的文档 |
$unwind |
将数组类型的字段进行拆分 |
常用表达式(聚合函数)
| 函数 |
描述 |
$sum |
计算总和,$sum:1同count表示计数 |
$avg |
计算平均值 |
$min |
获取最小值 |
$max |
获取最大值 |
$push |
在结果文档中插入值到一个数组中 |
$first |
根据资源文档的排序获取第一个文档数据 |
$last |
根据资源文档的排序获取最后一个文档数据 |
管道语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
db.集合.aggregate([{$group:{_id:'$字段',别名:{$聚合函数:'$字段名'}}])
db.集合.aggregate([{$match:{键名:{判断条件}}])
db.集合名.aggregate({ $project:{键名:1|0}});
db.集合名.aggregate({ $sort:{"键名":1|-1}});
db.集合名.aggregate({$limit:n});
db.集合名.aggregate({$skip:n});
db.集合名.aggregate({$unwind:'键名'});
|
使用参考
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| db.menpai.aggregate({$group:{_id:'$country',count:{$sum:1}}});
db.menpai.aggregate({$group:{_id:null,门派数:{$sum:1},平均分数: {$avg: '$score'}}});
db.menpai.aggregate({$group:{_id:'$sex',门派数:{$sum:1},门派名称:{$push:'$name'}}});
db.menpai.aggregate({$match:{"score":{$gt:85}}});
db.menpai.aggregate([ {$match:{"score":{$gt:85}}}, {$group:{_id:'$sex',总人数:{$sum:1}}} ]);
db.menpai.aggregate([ {$match:{"score":{$gt:85}}}, {$project:{_id:0,name:1, score:1}} ]);
db.menpai.aggregate([ {$match:{"score":{$gt:85}}}, {$project:{_id:0,name:1,score:1}}, {$sort:{'score':1}}, {$limit:4} ]);
db.menpai.aggregate([ {$match:{"score":{$gt:85}}}, {$unwind:'$skills'}, {$project:{_id:0,name:1,score:1,skills:1}}, ]);
|
索引
语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| db.collection.createIndex(keys, options)
db.col.getIndexes()
db.col.totalIndexSize()
db.col.dropIndexes()
db.col.dropIndex("索引名称")
|
| Parameter |
Type |
Description |
| background |
Boolean |
建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 “background” 可选参数。 “background” 默认值为false。 |
| unique |
Boolean |
建立的索引是否唯一。指定为true创建唯一索引。默认值为false. |
| name |
string |
索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。 |
| dropDups |
Boolean |
3.0+版本已废弃。在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false. |
| sparse |
Boolean |
对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false. |
| expireAfterSeconds |
integer |
指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。 |
| v |
index |
version |
| weights |
document |
索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。 |
| default_language |
string |
对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语 |
| language_override |
string |
对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language. |
参考
1 2 3 4
| db.col.createIndex({"title":1}) db.col.createIndex({"title":1,"description":-1}) db.col.createIndex({"createDate": 1},{expireAfterSeconds: 180})
|
调试
explain
explain,用于find()操作的情况查询
| 参数 |
描述 |
| queryPlanner |
默认参数,详细说明查询优化器选择的计划并列出被拒绝的计划 |
| executionStats |
MongoDB运行查询优化器选择获胜的计划,执行计划,完成并返回成功,统计描述的胜利计划的执行(查看命令耗时) |
| allPlansExecution |
MongoDB返回描述获奖计划的执行以及对其他候选人统计计划选择方案时捕获的统计 |
| 字段 |
描述 |
| nReturned |
表示该查询条件下返回的文档数量。 |
| executionTimeMills |
表示执行时间,单位毫秒 |
| totalDocsExamined |
表示该集合总共文档数。 |
1 2
| db.collectionName.find().explain(参数)
|
profiling
profiling,可以用于find()操作,但更多用于一些聚合查询之类的耗时统计。
| 参数 |
描述 |
| 0 |
不开启 |
| 1 |
记录慢命令(默认为>100ms) |
| 2 |
记录所有命令 |
| 字段 |
描述 |
| op |
操作类型 |
| ns |
被查的集合 |
| commond |
命令的内容 |
| docsExamined |
扫描文档数 |
| nreturned |
返回记录数 |
| millis |
耗时时间,单位毫秒 |
| ts |
命令执行时间 |
| responseLength |
返回内容长度 |
参考
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| db.setProfilingLevel(level , slowms) db.setProfilingLevel(1 ,10)
db.getProfilingLevel()
db.system.profile.find().pretty()
db.system.profile.find({millis:{$gt:50}})
db.system.profile.find().sort({$natural:-1}).limit(3)
db.system.profile.find({ns:'mydb.students'})
|
https://www.runoob.com/mongodb/mongodb-indexing.html
命令行
备份
- mongoimport和mongoexport主要用于开发和数据迁移场景
- mongodump和mongorestore主要用于数据库运维场景的备份与还原
- mongodump和mongorestore将整个数据库以备份形式导出和还原
- mongoexport和mongoimport以JSON、CSV和TSV格式导出导入集合级数据
导出 mongodump
可以导出整个数据库或单个集合
1 2 3 4 5 6 7 8 9 10 11
|
docker exec -it <容器名称> mongodump --db <数据库名称> --authenticationDatabase admin --username <用户名> --password <密码> --out <容器内导出目录>
docker exec -t <容器名称> mongodump --db <数据库名称> --collection <集合名称> --out <容器内导出目录>
docker exec -it mongo1 mongodump --db jihuang1 --authenticationDatabase admin --username admin --password admin12345 --out /data/backup/20231011
docker exec -it mongo1 mongodump --db jihuang1 --collection playerbaseinfo --authenticationDatabase admin --username admin --password admin12345 --out /data/backup/20231013
|
导入 mongorestore
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
docker exec -it <容器名称> mongorestore --db <数据库名称> --username <用户名> --password <密码> <容器内之前导出目录>
docker exec -it <容器名称> mongorestore --db <数据库名称> --collection <集合名称> <容器内bson文件路径>
docker exec -it mongo2 mongorestore --db jihuang2 --authenticationDatabase admin --username admin --password admin12345 /data/backup/20231015/jihuang1
docker exec -it mongo2 mongorestore --db jihuang2 --authenticationDatabase admin --username admin --password admin12345 --drop /data/backup/20231015/jihuang1
docker exec -it mongo2 mongorestore --db jihuang2 --authenticationDatabase admin --username admin --password admin12345 --noOptionsRestore --quiet /data/backup/20231015/jihuang1
docker exec -it mongo2 mongorestore --db jihuang3 --collection playerbaseinfo --authenticationDatabase admin --username admin --password admin12345 /data/backup/20231015/jihuang1/playerbaseinfo.bson
|
导出 mongoexport
只可以导出单个集合
1 2 3 4 5 6 7 8 9 10
| docker exec -it <容器名称> mongoexport --db <数据库名称> --collection <集合名称> --type <输出格式json、csv、tsv> --out <输出文件路径>
docker exec -it <容器名称> mongoexport --db <数据库名称> --collection <集合名称> --type <输出格式json、csv、tsv> --query <查询条件> --out <输出文件路径>
docker exec -it mongo2 mongoexport --db jihuang2 --collection playerbaseinfo --authenticationDatabase admin --username admin --password admin12345 --type json --out /data/backup/20231018/playerbaseinfo.json
docker exec -it mongo1 mongoexport --db jihuang2duat --collection playerbaseinfo --authenticationDatabase admin --username admin --password admin12345 --query '{"pid": 30002}' --type json --out /data/backup/uat_out/playerbaseinfo.json
|
导入 mongoimport
1 2 3 4 5
| docker exec -it <容器名称> mongoimport --db <数据库名称> --collection <集合名称> --file <容器内导入文件路径>
docker exec -it mongo2 mongoimport --db jihuang4 --collection playerbaseinfo --file /data/backup/20231018/playerbaseinfo.json --authenticationDatabase admin --username admin --password admin12345
|
bson转换
1 2 3 4 5 6
|
docker exec -it <容器名称> bsondump <容器内bson文件路径> > <容器外json文件输出路径>
docker exec -it mongo2 bsondump /data/backup/20231015/jihuang1/playerbaseinfo.bson > /data/docker/mongo2/backup/20231015/jihuang1/playerbaseinfo.json
|
删除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| docker exec -it mongo1 mongo <数据库名称> --eval "db.dropDatabase()" --authenticationDatabase admin --username admin --password admin12345
docker exec -it mongo1 mongo <数据库名称> --eval "db.<集合名称>.drop()" --authenticationDatabase admin --username admin --password admin1 2345
docker exec -it mongo1 mongo <数据库名称> --eval "db.<集合名称>.remove(<查询条件>)" --authenticationDatabase admin --username admin --password admin1
docker exec -it mongo1 mongo jihuang2d --eval "db.dropDatabase()" --authenticationDatabase admin --username admin --password admin12345
docker exec -it mongo1 mongo jihuang2d --eval "db.playerbaseinfo.drop()" --authenticationDatabase admin --username admin --password admin1 2345
docker exec -it mongo1 mongo jihuang2d --eval "db.playerbaseinfo.remove({\"pid\":1001})" --authenticationDatabase admin --username admin --password admin1 2345
|
链接
mongo官网
mongo手册