MongoDB的简介和特色
1. 易用性
MongoDB是一个面向文档(document-oriented)的数据库,而不是关系型数据库。
不采用关系型主要是为了获得更好得扩展性。当然还有一些其他好处,与关系数据库相比,面向文档的数据库不再有“行“(row)的概念取而代之的是更为灵活的“文档”(document)模型。
通过在文档中嵌入文档和数组,面向文档的方法能够仅使用一条记录来表现复杂的层级关系,这与现代的面向对象语言的开发者对数据的看法一致。
另外,不再有预定义模式(predefined schema):文档的键(key)和值(value)不再是固定的类型和大小。由于没有固定的模式,根据需要添加或删除字段变得更容易了。通常由于开发者能够进行快速迭代,所以开发进程得以加快。而且,实验更容易进行。开发者能尝试大量的数据模型,从中选一个最好的。
2、易扩展性(分布式)
由于需要存储的数据量不断增长,开发者面临一个问题:应该如何扩展数据库,分为纵向扩展和横向扩展,纵向扩展是最省力的做法,但缺点是大型机一般都非常贵,而且
当数据量达到机器的物理极限时,花再多的钱也买不到更强的机器了,此时选择横向扩展更为合适,但横向扩展带来的另外一个问题就是需要管理的机器太多。
MongoDB的设计采用横向扩展。面向文档的数据模型使它能很容易地在多台服务器之间进行数据分割。MongoDB能够自动处理跨集群的数据和负载,自动重新分配文档,以及将
用户的请求路由到正确的机器上。这样,开发者能够集中精力编写应用程序,而不需要考虑如何扩展的问题。如果一个集群需要更大的容量,只需要向集群添加新服务器,MongoDB就会自动将现有的数据向新服务器传送
3、丰富的功能
MongoDB作为一款通用型数据库,除了能够创建、读取、更新和删除数据之外,还提供了一系列不断扩展的独特功能
#1、索引
支持通用二级索引,允许多种快速查询,且提供唯一索引、复合索引、地理空间索引、全文索引
#2、聚合
支持聚合管道,用户能通过简单的片段创建复杂的集合,并通过数据库自动优化
#3、特殊的集合类型
支持存在时间有限的集合,适用于那些将在某个时刻过期的数据,如会话session。类似地,MongoDB也支持固定大小的集合,用于保存近期数据,如日志
#4、文件存储
支持一种非常易用的协议,用于存储大文件和文件元数据。MongoDB并不具备一些在关系型数据库中很普遍的功能,如链接join和复杂的多行事务。省略
这些的功能是处于架构上的考虑,或者说为了得到更好的扩展性,因为在分布式系统中这两个功能难以高效地实现
4、卓越的性能
MongoDB的一个主要目标是提供卓越的性能,这很大程度上决定了MongoDB的设计。MongoDB把尽可能多的内存用作缓存cache,视图为每次查询自动选择正确的索引。
总之各方面的设计都旨在保持它的高性能
虽然MongoDB非常强大并试图保留关系型数据库的很多特性,但它并不追求具备关系型数据库的所有功能。只要有可能,数据库服务器就会将处理逻辑交给客户端。这种精简方式的设计是MongoDB能够实现如此高性能的原因之一
二. MangoDB基础知识 ![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/f574645963b3ab5b5e106ef310813cfd.png)
二. MangoDB基本命令
show dbs | 查看数据库 |
---|---|
use DBName | 进入一个数据库,或者创建一个数据库 |
db | 查看当前数据库是什么 |
db.dropDatabase | 查看当前数据库是什么 |
db.createCollection(name,option) | 创建集合 |
db.collection.insert({" “:” "}) | 在集合中添加一条数据时会创建集合(首次) |
db.collectionName.drop() | 删除集合 |
db.collectionName.insertOne({}) | 在集合中添加一条数据 |
db.collectionName.insertMany([{},{}]) | 在集合中添加多条数据 |
db.collectionName.remove({删除的调节},justone]) | 删除文档数据,第二个参数为1表是仅仅删除一条 |
db.collectionName.updae(query,update,{upsert: boolean,multi: boolean,writeConcern: document}) | 在集合中添加多条数据,第三个参数 |
db.collectionName.save({:}) | _id 主键存在就更新,不存在就插入。 |
db.collectionName.find(query, projection) | query :可选,使用查询操作符指定查询条件 projection :可选,使用投影操作符指定返回键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。 |
注意:当一共数据库中没有collection的时候,show dbs是不能看见除了默认的
collection中的key可以有引号也可以没有,但是value是必须有
update参数说明
- query : update 的查询条件,类似 sql update 查询内 where 后面的。
- update : update的对象和一些更新的操作符(如, ,inc…)等,也可以理解为 sql update 查询内 set 后面的
- upsert 可选,这个参数的意思是,如果不存在 update 的记录,是否插入objNew,true 为插入,默认是false,不插入。
- multi 可选,mongodb 默认是 false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
- writeConcern :可选,抛出异常的级别。
createcolletions的options 可以是如下参数:
字段 | 类型 | 描述 |
---|---|---|
capped | 布尔 | (可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。当该值为 true 时,必须指定 size 参数。 |
autoIndexId | 布尔 | 3.2 之后不再支持该参数。 |
size | 数值 | (可选)为固定集合指定一个最大值,即字节数。如果 capped 为 true,也需要指定该字段。 |
max | 数值 | (可选)指定固定集合中包含文档的最大数量。 |
find
-
pretty()方法以格式化的方式来显示所有文档
-
MongoDB 条件操作符
- $gt -------- greater than >
- $gte --------- gt equal >=
- $lt -------- less than <
- $lte --------- lt equal <=
- $ne ----------- not equal !=
- $eq -------- equal
-
MongoDB 与 RDBMS Where 语句比较
操作 格式 范例 RDBMS 中的类似语句
等于 | {<key>:<value>} db.col.find({"by":"星星点灯"}).pretty() | where by = '菜鸟教程 |
---|---|---|
小于 | {<key>:{$lt:<value>}} db.col.find({"likes":{$lt:50}}).pretty() | where likes < 50 |
小于或等于 | {<key>:{$lte:<value>}} |db.col.find({"likes":{$lte:50}}).pretty() | where likes <= 50 |
大于 | {<key>:{$gt:<value>}} db.col.find({"likes":{$gt:50}}).pretty() | where likes > 50 |
大于或等于 | {<key>:{$gte:<value>}} db.col.find({"likes":{$gte:50}}).pretty() | where likes >= 50 |
不等于 | {<key>:{$ne:<value>}} db.col.find({"likes":{$ne:50}}).pretty() | where likes != 50 |
- MongoDB AND 条件
MongoDB 的 find() 方法可以传入多个键(key),每个键(key)以逗号隔开,即常规 SQL 的 AND 条件。语法格式如下:
db.col.find({key1:value1, key2:value2}).pretty()
或
db.col.find({‘$and’:[{key1:value1},{key2:value2}]}).pretty()
例如:
db.col.find({"by":"星星点灯", "title":"MongoDB 教程"}).pretty()
1
类似于 WHERE 语句:WHERE by=‘星星点灯’ AND title=‘MongoDB 教程’
4、MongoDB OR 条件
MongoDB OR 条件语句使用了关键字== $or==,语法格式如下:
db.col.find(
{
‘$or’: [
{key1: value1}, {key2:value2}
]
}).pretty()
例如:
db.col.find({‘$or’:[{"by":"星星"},{"title": "MongoDB
- AND 和 OR 联合使用
db.col.find({"likes": {$gt:50}, $or: [{"by": "星星点灯"},{"title": "MongoDB 教程"}]}).pretty()
- 模糊查询
查询 title 包含"教"字的文档:
db.col.find({title:/教/})
查询 title 字段以"教"字开头的文档:
db.col.find({title:/^教/})
查询 titl e 字段以"教"字结尾的文档:
db.col.find({title:/教$/})
- $type的类型判断和使用
在本章节中,我们将继续讨论MongoDB中条件操作符 $type。
$type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果。
类型 | 数字 | 备注 |
---|---|---|
Double | 1 | |
String | 2 | |
Object | 3 | |
Array | 4 | |
Binary | data | 5 |
Undefined | 6 | 已废弃。 |
Object id | 7 | |
Boolean | 8 | |
Date | 9 | |
Null | 10 | |
Regular | Expression | 11 |
JavaScript | 13 | |
Symbol | 14 | |
JavaScript (with scope) | 15 | |
32-bit integer | 16 | |
Timestamp | 17 | |
64-bit integer | 18 | |
Min key | 255 | Query with -1. |
Max key | 127 |
如果想获取 “col” 集合中 title 为 String 的数据,你可以使用以下命令:
db.col.find({"title" : {$type : 2}})
- limit()
实例
集合 col 中的数据如下:
{ "_id" : ObjectId("56066542ade2f21f36b0313a"),
"title" : "PHP 教程", "description" :
"PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。",
"by" : "菜鸟教程", "url" : "http://www.runoob.com",
"tags" : [ "php" ], "likes" : 200 } ,
{ "_id" : ObjectId("56066549ade2f21f36b0313b"),
"title" : "Java 教程",
"description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。",
"by" : "菜鸟教程", "url" : "http://www.runoob.com",
"tags" : [ "java" ], "likes" : 150 } ,
{ "_id" : ObjectId("5606654fade2f21f36b0313c"),
"title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库",
"by" : "菜鸟教程", "url" : "http://www.runoob.com",
"tags" : [ "mongodb" ], "likes" : 100 }
> db.col.find({},{"title":1,_id:0}).limit(2) { "title" : "PHP 教程" } { "title" : "Java 教程" } >
- skip()
>db.col.find({},{"title":1,_id:0}).limit(1).skip(1) { "title" : "Java 教程" } >
find函数的第二个参数,是指要显示的内容,0表示不显示,1表示显示
数据的聚会,排序,规约处理
- sort()
在MongoDB中使用使用sort()方法对数据进行排序,sort()方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而-1是用于降序排列。
以下实例演示了 col 集合中的数据按字段 likes 的降序排列:
>db.col.find({},{"title":1,_id:0}).sort({"likes":-1})
> { "title" : "PHP 教程" } { "title" : "Java 教程" } { "title" : "MongoDB 教程" }
>
注:= 如果没有指定sort()方法的排序方式,默认按照文档的升序排列。
索引
ensureIndex() 方法
MongoDB使用 ensureIndex() 方法来创建索引。
语法
ensureIndex()方法基本语法格式如下所示:
db.COLLECTION_NAME.ensureIndex({KEY:1})
Parameter | Type | Description | |
---|---|---|---|
background | Boolean | 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 “background” 可选参数。 “background” 默认值为false。 | |
unique | Boolean | 建立的索引是否唯一。指定为true创建唯一索引。默认值为false. | |
name | string | 索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。 | |
dropDups | Boolean | 在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false. | |
sparse | Boolean | 对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false. | |
expireAfterSeconds | integer | 指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。 | |
v | index version | 索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。 | |
weights | document | 索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。 | |
default_language | string | 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语 | |
language_override | string | 对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language. |
聚合
MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。有点类似sql语句中的 count(*)。
实例
集合中的数据如下:
{ title: 'MongoDB Overview',
description: 'MongoDB is no sql database',
by_user: 'w3cschool.cc',
url: 'http://www.w3cschool.cc',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100 },
{ title: 'NoSQL Overview',
description: 'No sql database is very fast',
by_user: 'w3cschool.cc',
url: 'http://www.w3cschool.cc',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 10 },
{ title: 'Neo4j Overview',
description: 'Neo4j is no sql database',
by_user: 'Neo4j',
url: 'http://www.neo4j.com',
tags: ['neo4j', 'database', 'NoSQL'],
likes: 750 }
现在我们通过以上集合计算每个作者所写的文章数,使用aggregate()计算结果如下:
> db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
{
"result" : [
{
"_id" : "w3cschool.cc",
"num_tutorial" : 2
},
{
"_id" : "Neo4j",
"num_tutorial" : 1
}
],
"ok" : 1
}
>
注意:1,aggregate的参数必须是一个数组
2,
g
r
o
u
p
对
应
的
文
档
对
象
必
须
有
一
共
i
d
属
性
是
分
组
的
属
性
,
3
,
“
group对应的文档对象必须有一共 id 属性是分组的属性, 3,“
group对应的文档对象必须有一共id属性是分组的属性,3,“自定义的可以key”表示的含义就是对应的key的值
表达式 | 描述 | 实例 | |
---|---|---|---|
$sum | 计算总和。 | db.mycol.aggregate([{$group : {_id : " $by_user" , num_tutorial : {$sum : "$likes"}}}]) | |
$avg | 计算平均值 | db.mycol.aggregate([{$group : {_id : " $by_user ", num_tutorial : {$avg : "$likes"}}}]) | |
$min | 获取集合中所有文档对应值得最小值。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}]) | |
$max | 获取集合中所有文档对应值得最大值。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}]) | |
$push | 在结果文档中插入值到一个数组中。 | db.mycol.aggregate([{$group : {_id : " $by_user ", url : {$push: "$url"}}}]) | |
$addToSet | 在结果文档中插入值到一个数组中,但不创建副本。 | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}]) | |
$first | 根据资源文档的排序获取第一个文档数据。 | db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}]) | |
$last | 根据资源文档的排序获取最后一个文档数据 | db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}]) |
注意:aggregate中的$group用id对应的key变量分组时,没有对应的key的对象会分为一组
grop的本质就是根据对应的id属性进行分组,第二个参数就是如何处理分组后的数组
上面$push的执行结果=
{ "_id" : null, "url" : [ "http://www.runoob.com", "http://www.runoob.com", "http://www.runoob.com" ] }
{ "_id" : "w3cschool.cc", "url" : [ "http://www.w3cschool.cc", "http://www.w3cschool.cc" ] }
{ "_id" : "Neo4j", "url" : [ "http://www.neo4j.com" ] }
管道的概念
管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。
MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。
这里我们介绍一下聚合框架中常用的几个操作:
$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
$match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
$limit:用来限制MongoDB聚合管道返回的文档数。
$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$group:将集合中的文档分组,可用于统计结果。
$sort:将输入文档排序后输出。
$geoNear:输出接近某一地理位置的有序文档。
管道操作符实例
1、$project实例
表示只保留为1的对应的属性,_id属性是默认保存的
db.article.aggregate(
{
$project : {
title : 1 ,
author : 1 ,
}
}
);
MongoDB 复制(副本集)
MongoDB复制是将数据同步在多个服务器的过程。
复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性。
复制还允许您从硬件故障和服务中断中恢复数据。
什么是复制?
保障数据的安全性
数据高可用性 (24*7)
灾难恢复
无需停机维护(如备份,重建索引,压缩)
分布式读取数据
MongoDB复制原理
mongodb的复制至少需要两个节点。其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据。
mongodb各个节点常见的搭配方式为:一主一从、一主多从。
主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。
MongoDB复制结构图如下所示:
以上结构图总,客户端总主节点读取数据,在客户端写入数据到主节点是, 主节点与从节点进行数据交互保障数据的一致性。
副本集特征:
N 个节点的集群
任何节点可作为主节点
所有写入操作都在主节点上
自动故障转移
自动恢复