MongoDB基础部分及实现(二)

来源:互联网 发布:淘宝信用查询网 编辑:程序博客网 时间:2024/05/01 04:15

MongoDB基础部分及实现(二)

 

MongoDB是由C++语言所编写的一种面向文档的非关系型数据库(是一种NoSql数据库实现),也是介于关系型数据库和非关系型数据库之间的数据存储产品,其提供了高性能、高可用、高可拓展及基于分布式存储的数据库,是非关系型数据库中功能最丰富,最类似关系型数据库的一种集合、文档格式的数据库。

 

l   索引

l   分析

l   聚合

l   监控

 

一、索引

MongoDB中的索引与RDBMS中的索引原理相同,主要就是当检索索引字段或文档属性数据时,一旦检索到满足条件的数据,数据库引擎会即刻返回结果,不做数据库的全文检索,可以大大提高数据的检索效率。

 

1、索引语法

在MongoDB中使用索引,我们需要使用ensureIndex()方法,格式如下:

>db.COLLECTION_NAME.ensureIndex({KEY:1,KEY:-1,…},{options})

NOTE:

1代表升序排列

-1代表降序排列

 

另外,ensureIndex()也可以接受一些可选的功能参数options,具体如下:

参数

类型

描述

background

Boolean

在后台建立索引,以便建立索引时不会阻止其他数据库操作,默认值为false,代表未在后台创建索引。

unique

Boolean

创建唯一索引,代表创建索引的文档不能出现重复的文档记录,默认值是 false,代表创建非唯一索引。

name

string

索引的名称,如果未指定,MongoDB引擎会生成一个索引字段的名称和排序顺序串联的名字,实际使用时建议指定索引名字,方便后续对索引维护。

dropDups

Boolean

创建唯一索引时,可能有重复文档记录,指定该参数为true时,会删除非第一条文档的其余重复文档。

sparse

Boolean

对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档。

expireAfterSeconds

integer

使用TTL可以设置一个时间范围,如果到了此范围,文档被删除。

v

index version

索引版本号。默认的索引版本取决于mongodb 运行的版本。

weights

document

权重是从199999范围内的数,表示该字段的意义,相对于其他的索引字段分数比重。

default_language

string

如果您将语言指定为值 "none" ,那么 text search 会使用简单的分词器,没有停止词也没有取词根处理。默认值是english

language_override

string

如果语言字段没有language字段,而是别的字段,那么在索引创建的时候,使用language_override指向这个字段。

 

注意:

上面的几个参数并非都常用,读者只需要根据实际使用,熟练使用几个即可,例如:backgrounduniquenamedropDupssparse

 

2、创建使用

我们就以mydb数据库中的post集合为例,在其文档的title和desc连个字段上建立唯一索引,并设置该动作在后台创建,同时指定该索引的名字,具体如下操作:

>db.post.ensureIndex({'title':1,'desc':-1},{background:true,unique:true,name:'idx_post_title_desc'})

结果显示:

 

那么,如何知道索引是否工作?请继续查看第二部分:分析,该部分就以该索引为例进行分析查询的信息。

 

二、分析

我们分析第一部分创建的唯一索引,以mydb数据库的集合post查询为例分析并查看结果显示。在MongoDB中,系统提供了explain和hint两种方式来分析查询的信息。

1、explain

 在MongoDB中,explain是非常有用的工具,可以帮助获得查询方面很多有用的信息;只要对游标调用该方法,就可以得到查询细节,并且explain会返回一个文档,而不是游标本身,具体如下使用:

>db.post.find({"title":"MongoDB"}).explain()

 

结果显示:

 

NOTE:

 stage:代表本次查询为索引类型查询;

 keyPattern:代表该索引所属的文档字段;

 indexName:代表索引的名字;

 isUnique:代表该索引为唯一索引;

 

2、hint

在MongoDB中,可以使用hint操作符强制查询优化器使用指定索引来运行一个查询,这在查询某个索引的性能方面很实用,具体如下:

>db.post.find({"title":"MongoDB"}).hint({"title":1})

{ "_id" :ObjectId("57e10bd076be84c977b7acda"), "title" :"MongoDB", "desc" : "database", "likes": NumberLong(100000), "url" : "http://www.cwteam.com","by" : "cwteam.com" }

接下来,我们使用explain分析上面的查询:

>db.post.find({"title":"MongoDB"}).hint({"title":1}).explain()

 

结果显示:

 

NOTE:

这里使用hint强制本次查询使用索引idx_post_title_desc_new。

 

三、聚合

聚合操作过程中,从多个文档中计算结果并返回,并可以执行各种操作,分组数据返回单个结果。

1、语法格式

MongoDB中,我们需要使用aggregate()方法来实现聚合的各种操作,具体格式如下:

>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

常用的聚合方法列表如下:

表达式

描述

实例

$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

根据分组从源文档中获取的第一个文档。通常情况下,连同以前的一些应用 “$sort”-stage.

db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])

$last

根据分组从源文档中获取最后的文档。通常,连同以前的一些应用 “$sort”-stage.

db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])

 

注意:

上面的几个参数并非都常用,读者只需要根据实际使用,熟练使用几个即可,例如:sumavgminmaxpush

 

2、如何使用

这里我们同样以mydb数据库中的post集合为例,数据格式如下:

然后,我们使用方法aggregate()按by分组,并计算各个分组中的文档个数,具体如下操作及显示:

>db.post.aggregate([{$group:{_id:"$by",num_bys:{$sum:1}}}])

{ "_id" : "jakeup.com","num_bys" : 1 }

{ "_id" :"cwteam.com", "num_bys" : 2 }

 

NOTE:

如上所示,共分两组,一组文档个数为1,另一组文档个数为2。

 

四、监控

在MongoDB中,其本身提供了两种常用的状态监控工具,分别为mongotop和mongostat。在实际使用MongoDB数据库时,我们需要间隔固定时间检测下所有启动的MongoDB服务的状态,或是当数据操作缓慢及其它问题时,我们最先考虑的是使用它们来测试下当前的实例状态,再而修复问题。

1、mongostat

mongostat工具会间隔固定时间获取并输出mongodb的当前运行状态,一般发现数据库变慢或是其他问题时,首先考虑使用其对实例服务进行侦测。

具体使用如下:

$sudo ./mongostat

 

输出结果显示:



结果参数说明:

insert/query/update/delete->每秒插入/查询/更新/删除的次数;

getmore->每秒执行getmore的次数;

command->每秒实例执行命令数目;

dirty->是否生成脏数据以及其大小;

used->实例空间被使用的大小;

flushes->每秒执行fsync数据写入的次数;

vsize->虚拟内存使用量,单位为G;

res->物理内存使用量,单位为MB;

qr|qw->当Mongodb接收到太多的命令而数据库被锁住无法执行完成,它会将命令加入队列。这一栏显示了总共、读、写3个队列的长度,都为0的话表示mongo毫无压力。高并发时,一般队列值会升高。

ar|aw->当前被激活的连接客户端数量,值越大越阻碍mongodb的性能。

netIn/netOut->网络带宽压力值,一般mongodb来说,网络不会成为瓶颈。

conn->当前连接数;

 

监控输出日志:

$sudo ./mongostat –n 10 >/mongodb/logs/stat_log.txt

上面即为将10行监听的结果输出到stat_log.txt文件中,方便查询分析。

输出结果显示:

 

如果实际中,服务器比较繁忙时,我们可以使用db.currentOp()快速获取当前执行的核心操作,具体如下所示:

 

如上图,inprog[]非空时,一般代表该台服务器有一定负载,这时我们可以查看一些耗时或是无用的操作,通过其opid停止掉它,具体如下:

> db.killOp(5098)

{ "info" :"attempting to kill op", "ok" : 1 }

 

另外,10gen公司发布一个web版本MongoDB监控服务工具,我们可以注册并使用其来更清晰化的监控信息,其工作原理及流程如下:

•            在MMS服务器上配置你的MongoDB信息(Host,Port,User,Passwd等)

•            在一台能够访问你MongoDB服务的内网机器上运行其提供的Agent脚本

•            Agent脚本从MMS服务器获取到你配置的MongoDB信息

•            Agent脚本连接到相应的MongoDB获取必要的监控数据

•            Agent脚本将监控数据上传到MMS的服务器

•        登录MMS网站查看整理过后的监控数据图表了

 

具体操作这里不说明,有需要的伙伴可以直接去10gen官网注册并配置好自己的MongoDB服务就可以查看了,接下来我们来看下另一个监控工具mongotop的特点和它的使用。

 

 

2、mongotop

mongotop也是MongoDB的一内置工具,它的作用与mongostat类似,不够其注重监控的是实例的读写以及集合的统计数,偏向于整体结果显示,具体如下使用:

$sudo ./mongotop 5

上面的5代表间隔5秒的时长返回监控的结果输出,当然也可以设置,默认按每秒返回显示。

 

结果显示:

 

 

参数说明:

ns->数据库命名空间、名称和集合;

total->当前命名空间工作的时间总额;

read->当前命名空间的读取数据的时间速度;

write->当前命名空间的写入数据的时间额度

 

 

 

 

 

 

 

 

 

好了,Mongodb基础部分(二)就介绍到这里,由于作者水平有限,如有问题请在评论发言或是QQ群讨论,谢谢。

 

 

 

 

技术讨论群:

276592700(新)

1 0
原创粉丝点击