概述
开源 免费 技术支持
使用案例:
国外:ebay sourceforge github
国内:淘宝 京东 百度 360 大众点评mongoDB中的概念
- mongoDB
- mongo
- 索引(index)
- 集合(Set)
- 复制集
- 分片(Slice)
- 数据均衡
mongoDB的搭建
部署数据库服务- 搭建简单的单机服务
- 搭建具有冗余容错功能的复制集
- 搭建大规模数据集群
- 完成集群的自动部署
mongoDB的使用
- 最基本的文档的读写更新删除
- 各种不同类型索引的创建与使用
- 复杂的聚合查询
- 对数据集合进行分片,在不同分片中维持数据均衡
- 数据备份与恢复
- 数据迁移
简单运维
- 部署mongoDB集群
- 处理多种常见的故障
- 单节点失效,如何恢复工作
- 数据库意外被杀死,如何进行数据恢复
- 数据库拒绝服务,如何排查原因
- 数据库磁盘快满时如何处理
网站
- 官网:www.mongodb.org
编译文件, 英文文档 - 国内官网:www.mongoing.com
中文翻译文档(不全) - github: github.com/mongodb
mongoDB源码, mongoDB驱动
- 官网:www.mongodb.org
数据库分类
- Sql数据库:支出Sql语言的数据库
Oracle, Mysql
有表,有事务支持 - NoSql数据库(Not Only SQL):不支持Sql语言的数据库
redis, mongoDB - 比较
|——————|——————-|
| Sql数据库 | NoSql数据库 |
|——————|——————-|
| 实时一致性 | 简单便捷 |
| 事务 | 方便扩展 |
|多表联合查询| 更好的性能 |
|——————|——————-|
redis支持事务,mongoDb不支持事务。
- Sql数据库:支出Sql语言的数据库
MongoDB的安装与部署
从官网下载二进制文件或者下载源码自己编译
源码说明
mongod
数据库的服务程序mongo
数据库的客户端mongimport
导入
mongexport
导出mongodump
导出二进制
mongorestore
导入二进制,一般用于作数据库的备份与恢复mongooplog
操作日志mongostat
数据库状态
搭建简单的mongoDB服务器
创建数据库目录
|— mongodb_simple 数据库目录
| |— data 数据目录
| |— log 日志目录
| |— conf 配置目录
| |— bin 数据库的二进制文件将
mongod
拷贝到./bin
目录创建启动文件
./conf/mongod.conf
1
2
3
4port = 12345 ; 监听端口
dbpath = data ; 数据库数据目录, 可以是相对路径或绝对路径
logpath = log/mongod.log ; 日志文件
fork = true ; 启动后台进程windows下的镜像自带有配置文件,位置为:
.\bin\mongod.cfg
默认监听端口为:27017
, 并且dbpath
和logpath
需要写绝对路径。启动mongod
1
./bin/mongod -f conf/mongod.conf
-f 指定启动文件
或为保证数据库的安全性,使用下面的方式:
1
numactl --interleave=all bin/mongod -f conf/mongod.conf
- windows下MongoDB配置服务
1) 配置服务2) 启动服务1
2# 管理员权限的控制台
mongod --config "D:\MongoDB\Server\4.0\conf\mongod.conf" --install --serverName "MongoDB"3) 停止服务1
net start MongoDB
4) 删除服务1
net stop MongDB
可以将1
sc delete MongoDB
bin
目录添加到环境变量,这样不需要每次使用都进入mongoDB的安装目录。
连接mongoDB服务器
查看所有数据库
1
show dbs
- 选择使用数据库
1
use dbname
删除数据库
1
db.dropDatabase()
在mongoDB中不需要手动创建数据库,
会在需要的时候自动创建。插入数据
db.dbname_collection.insert(JSON)
eg:1
db.imooc_collection.insert({x:1})
imooc_collection是一个数据集。
查询数据
db.dbname_collection.find([JSON])
db.dbname_collection.findOne() 查询一条数据
eg:1
2db.imooc_collection.find() # 查询所有数据
db.imooc_collection.find({x:1}) # 查询x为1的是数据mongoDB中默认主键为
_id
.
find()
支持skip
(跳过多条数据),limit
(限制数据条数),
sort
(数据排序)。1
for(i=3; i<100; i++) db.imooc_collection.insert({x:i})
mongoDB可以支持JS语法插入数据。
1
db.imooc_collection.find().count()
对查询结果进行计数。
1
db.imooc_collection.find().skip(3).limit(2).sort({x:1})
数据更新
db.dbname_collection.update(condition_JSON, data_JSON, insert_boolean, all_boolean)1
db.imooc_collection.update({x:1}, {x:999})
更新全部x=1的数据为x=999
案例1:
1
2db.imooc_collection.insert({x:100, y:100, z:100})
db.imooc_collection.update({z:100}, {y:99})这种情况下更新的数据是:所有z=100的数据更新为y=99,
而x,z的数据会被覆盖。如何更新一行中的某个元素?在update中使用
set
操作。1
2db.imooc_collection.insert({x:100, y:100, z:100})
db.imooc_collection.update({z:100}, {$set:{y:99}})需求:如果更新一条数据时,数据不存在,则插入数据
方法:设置update()的第三个参数为true.1
db.imooc_collection.update({y:100}, {y:999}, true)
mongoDB中默认更新第一条匹配的数据, 这样设计是为了防止误操作。
如何更新所有匹配的数据?使用
set
操作符,update第四个参数设置为true.1
db.imooc_collection.update({c:1}, {$set: {c:2}}, false, true)
数据删除
db.dbname_collection.remove(JSON)
与find()不同的是,remove为防止误操作,必须传入参数。
与update()不同的是,remove默认删除所有匹配的数据。1
db.imooc_collection.remove({c:2})
对于某张表(数据集)使用删除操作,可以使用:
db.dbname_collection.drop()1
2db.imooc_collection.drop()
show tables创建索引
查看集合的索引情况:db.dbname_collection.getIndexes()1
db.imooc_collection.getIndexes()
创建索引:
db.dbname_collection.ensureIndex(JSON)1
db.imooc_collection.ensureIndex({x:1})
1表示正序,-1代表负向排序。
mongoDB常见的查询索引
db.collection.ensureIndex({param1},{param2})
param1: 索引的值。
param2: 索引的属性。
索引的种类与使用
_id索引
_id是绝大多数集合默认建立的索引。
对于每个插入的数据,mongoDb都会自动生成一条唯一的_id字段。单键索引
最普通的索引,并不会自动创建。
使用ensureIndex()
创建。多键索引
与单键索引创建形式相同,区别在于字段的值。
单键索引:值为一个单一的值,例如字符串,数字或者日期。
多键索引:值具有多个记录,例如数组。
eg:1
db.imooc_collection.insert({x:[1,2,3,4,5]})
x即为多键索引。
复合索引
当查询条件不只有一个时,就需要创建复合索引。
逻辑:插入{x:1,y:2,z:3}记录->按照x与y的值查询->创建索引:db.collection.ensureIndex({x:1, y:1}) ->使用{x:1, y:1}作为条件进行查询。
1
2db.imooc_collection.ensureIndex({x:1, y:1})
db.imooc_collection.find({x:1, y:2})过期索引
是在一段时间后会过期的索引。
在索引过期后,相应的数据会被删除。
这适合存储一些在一段时间之后会失效的数据,
比如用户的登陆信息,存储的日志。
建立方法:db.collection.ensureIndex({time:1},{expireAfterSecond:10})
time
是键值,expireAfterSecond
表示秒数。1
2
3db.imooc_collection.ensureIndex({time:1}, {expireAfterSecond:30})
db.imooc_collection.insert({time: new Date()})
db.imooc_collection.find()过期索引的限制:
- 存储在过期索引字段的值必须是指定的事件类型。
必须是ISODate或者ISODate数组,不能使用时间戳,否则不能自动删除。 - 如果指定了ISODate数组,则按照最小的时间进行删除。
- 过期索引不能是复合索引。
- 删除时间是不精确的。删除进程在后台每60s跑一次。
- 存储在过期索引字段的值必须是指定的事件类型。
全文索引
对字符串和字符数组创建全文可搜索的索引。
适用情况:{author:””, title:””, article:””}
创建方法:- db.articles.ensureIndex({key:”text”})
- db.articles.ensureIndex({key_1:”text”, key_2:”text”})
- db.articles.ensureIndex({“$**”:”text”})使用全文索引查询:
1
db.imooc_collection.ensureIndex({"article":"text"})
db.article.find({$text: {$search:”coffe”}})
db.article.find({$text: {$search:”aa bb cc”}} 使用空格分隔多个关键词(或
查找)。
db.article.find({$text: {$search:”aa bb -cc”}} 不包含cc
db.article.find({$text: {$search:”\”aa\” \”bb\” \”cc\””}}与
查找全文索引的相似度查询:1
2
3
4
5
6db.imooc_collection.insert({"article":"aa bb cc dd ee"})
db.imooc_collection.insert({"article":"aa bb rr gg"})
db.imooc_collection.insert({"article":"aa bb cc hh gg"})
db.imooc_collection.find({$text: {$sarch:"aa"}})
db.imooc_collection.find({$text: {$sarch:"aa rr"}})
db.imooc_collection.find({$text: {$sarch:"\"aa\" \"rr\""}})$meta
操作符: {score: {$meta:”textScore”}}
写在查询条件后面可以返回查询结果的相似度。
与sort
一起使用,可以达到很好的实用效果。全文索引使用限制:1
2
3db.imooc_collection.find({$text: {$search:"aa bb"}})
db.imooc_collection.find({$text: {$search:"aa bb"}}, {score: {$meta: "textScore"}})
db.imooc_collection.find({$text: {$search:"aa bb"}}, {score: {$meta: "textScore"}}).sort({score: {$meta: "textScore"}) - 每次查询,只能指定一个$text查询
- $text拆线呢不能出现在$nor查询中
- 查询中如果包含了$text, hint不再起作用
- MongoDB的全文索引还不支持中文
地理位置索引
概念:将一些点的位置存储在mongoDB中,创建索引后,
可以按照位置来查找其他点。子分类:1) 2D索引,用于存储和查找平面上的点。
2) 2DSphere索引,用于存储和查找球面上的点。查找方式:
1) 查找距离某个点一定距离内的点。
2) 查找包含在某个区域内的点。2D索引
db.collection.ensureIndex({w:”2d”})w
是字段名,2d
固定。1
db.location.ensureIndex({"w":"2d"})
位置表示方式:经纬度[经度, 纬度]
取值范围:经度[-180, 180] 纬度[-90, 90]1
2
3
4
5db.location.insert({w:[1,1]})
db.location.insert({w:[1,2]})
db.location.insert({w:[3,1]})
db.location.insert({w:[100,80]})
db.location.insert({w:[180,80]})查询方式:
1)$near
查询:查询距离某个点最近的点。
2)$geoWithin
查询:查询某个形状内的点。$near
查询:1
db.location.find({w:{$near:[1,1]}})
$near默认会返回100个距离[1,1]的点,
可以使用$maxDistance
设置扫描半径。1
db.location.find({w:{$near:[1,1], $maxDistance:10}})
同理也有
$minDistance
选项,但是2D索引中不支持这个。形状的表示:
1)$box
:矩形,使用{$box:[[<x1>,<y1>],[<x2,<y2>>]]}
表示。
使用两个坐标表示,第一个是左上角坐标,第二个是右下角坐标。2)
$center
:圆形,使用{$center:[[<x1>,<y1>], r]}
表示。
使用圆心和半径表示,第一个参数是圆心坐标,第二个参数是半径长度。3)
$polygon
:多边形,使用{$polygon:[[<x1>,<y1>],[<x2>,<y2>],[<x3>,<y3>]]}
表示。
参数为一个数组,数组内是点的坐标,组成一个多边形。$geoWithin
查询:1
2
3
4db.location.find({w:{$geoWithin:{$box:[[0,0],[3,3]]}}})
db.location.find({w:{$geoWithin:{$box:[[1,1],[2,3]]}}})
db.location.find({w:{$geoWithin:{$center:[[0,0], 4]}})
db.location.find({w:{$geoWithin:{$polygon:[[0,0], [1,1], [0,2], [2,2]]}}})使用
geoNear查询
:
geoNear使用runCommand
命令进行使用,常用使用如下:1
2
3
4
5
6
7
8db.runCommand({
geoNear:<collection>,
near:[x,y],
minDistance:(对2d索引无效),
maxDistance: ,
num: ,
...
})eg:
1
db.runCommand({geoNear:"location", near:[1,2], maxDistance:10, num:2})
- 2DSphere索引
db.collection.ensureIndex({w:”2dsphere”})
位置表示方式:
GeoJSON:描述一个点,一条直线,多边形等形状。
格式:
{type: “”, coordinates:[]}
支持$minDistance与$maxDisctance
索引属性
重要的索引属性:名字,唯一性,稀疏性,是否定时删除名称(
name
)属性1
2
3db.imooc_collection.ensureIndex({x:1})
db.imooc_collection.ensureIndex({y:-1}) # 排序方向为负
db.imooc_collection.getIndexes()创建了索引x,使用getIndexes()获取索引,查看索引名称为:
"name":"x_1"
"name":"y_-1
=> 索引的命名方式是key_1
或者key_-1
1
2db.imooc_collection.ensureIndex({x:1, y:-1})
db.imooc_collection.getIndexes()创建复合索引,获取复合索引名称为:
x_1_y_-1
=>索引的命名方式是:多个键之间使用_
连接。
mongoDB的索引最大长度是125,为此,key太多的情况下索引名称会很长。
可以在创建索引的时候指定索引的名称:1
2db.imooc_collection.ensureIndex({x:1,y:1,z:1,m:1},{name:"normal_index"})
db.imooc_collection.getIndexes()查看索引名称为:
"name":"normal_index"
在删除索引时,也可以使用指定的名称删除:
1
db.imooc_collection.dropIndex("normal_index")
- 唯一性(
unique
)属性
db.collection.ensureIndex({},{unique:true/false})
作用:如果为唯一索引,则在集合中不允许出现两个相同的记录。1
2
3db.imooc_collection.ensureIndex({m:1, n:1}, {unique:true})
db.imooc_collection.insert({m:1, n:2})
db.imooc_collection.insert({m:1, n:2}) # 报错: duplicate key - 稀疏性(
sparse
)和expireAfterSeconds
指定
db.collection.ensureIndex({}, {sparse:true/false})
作用:默认创建的是非稀疏的,true/false表示了mongoDB处理数据时3的两种不同方法。。
mongoDB在插入一条新记录时,如果某个字段原来不存在,
mongoDB默认会新建该字段;如果不希望这种情况发生,则设置稀疏性为true.1
2
3
4db.imooc_collection.insert({"m":1})
db.imooc_collection.insert({"n":1})
db.imooc_collection.find({m:{$exists:true}})
db.imooc_collection.find({m:{$exists:false}})$exists
操作符可以获取存在该字段的记录。创建m的稀疏索引,1
2db.imooc_collection.ensureIndex({m:1},{sparse:true})
db.imooc_collection.find({m:{$exists:false}}).hint("m_1")hint
表示强制使用索引。 - 过期属性
expireAfterSecond
指定. TTL,过期索引。
索引的匹配规则
如何建立合适的索引
索引建立的情况评估
索引好处:加快索引相关的查询。
索引坏处:增加磁盘空间消耗,降低写入性能。mongostat
工具
使用:mongostat -h 127.0.0.1:27017
profile
集合介绍日志介绍
explain
分析
db.collection.find().explain()
mongoDB安全
mongoDB安全楔子
- 最安全的是物理隔离:不现实
- 网络隔离其次
- 防火墙再其次
- 用户名密码在最后
开启权限认证
- auth开启
在mongod.conf
中附加:角色类型:内建类型(read, readWrite, dbAdmin, dbOwner, userAdmin)1
2
3
4
5
6
7
8
9
10需要重启mongod服务。
再在mongoDB中创建用户:
1) 创建语法:`createUser`(2.6之前为addUser)
```shell
{
user: "<name>",
pwd: "<cleartext password>",
customData: {<any information>},
roles: [{role: "role", db: "<database>"}]
}
eg:登陆:1
db.createUser({user:"imooc", pwd:"imooc", customData:"示例",roles:[{role:"userAdmin", db:"admin"},{role:"read",db:"test"}]})
角色详解:1
mongod 127.0.0.1:27017/imooc -u imooc -p imooc
1) 数据库角色:read, readWrite, dbAdmin, dbOwner, userAdmin
2) 集群角色:clusterAdmin, clusterManager…
3) 备份角色:backup, restore…
4) 其它特殊权限:DBAdminAnyDatabase…
mongoDB中创建用户角色:
- auth开启