资讯专栏INFORMATION COLUMN

Mongodb聚合查询及在日常运维中的使用

IT那活儿 / 3651人阅读
Mongodb聚合查询及在日常运维中的使用
点击上方蓝字关注我们


一、Mongodb聚合查询介绍


Mongodb是一种基于JSON文档的NOSQL数据库,其数据查询语言我们称之为MQL,如:

db.collectionA.find();--相当于select* from connectionA;

db.inventory.find({ status: “A” }, { item: 1, status: 1 } )  --相当于SELECT_id, item, status from inventory WHERE status = "A“

Find命令只适合用于单表查询(包括嵌套文档和数组查询)

Mongo中的复杂查询、多集合连接查询以及数据分析和计算,均需要使用到聚合查询。,格式如下:

db.collection.aggregate([{stage},{stage},……,{stage}]);

其中stage是聚合的一个步骤,每个stage都是一个json文档。


二、聚合查询详细讲解


Mongodb的聚合架构是基于管道,按照stage顺序执行,类似于shell命令的管道,如:

ps–ef|grep LOCAL=NO|awk ‘{print $2}’|xargs kill -9 ,其处理过程为:


聚合查询处理过程如下:

其处理过程为:

转换成SQL相当于:

Selectcust_id,sum(amount) from orders where status=‘a’ group bycust_id;



三、常用的聚合stage和运算符


常用的stage:

stage

用途

SQL等价运算符

备注

$match

过滤

WHERE、having


$project

投影

SELECT


$group

分组

group by


$lookup

连接查询

LEFT OUT JOIN

在mongodb中建议使用嵌套文档,减少连接查询

$unwind

拆解数组为文档



$sort

排序

ORDER BY



常用的运算符:

运算符

用法

$eq/$gt/$gte/$lt/$lte

"=/>/>=/<=/<"

$and/$or/$not/$in

and or not in

$split

按照分隔符将字符串拆成数组

$sum

sum()

$avg/$min/$max

avg(),max(),min()

$push

将文档构成数组


四、聚合查询示例


1

源数据:

按照item进行分组统计quantity的和。

Selectitem,sum(quantity) from c1 group by item;对应聚合查询如下:

db.c1.aggregate(

       [

                 {$group:

                          {_id:"$item",

                          sum_quantity:{$sum:"$quantity"}

                          }

                  }

       ]

);


结果:

按照item进行分组统计quantity的和,且结果大于10

Selectitem,sum(quantity) from c1 group by item having sum(quantity)>10;对应聚合查询如下:

db.c1.aggregate(

       [

                {$group:

                          {_id:"$item",

                          sum_quantity:{$sum:"$quantity"}}

                  },

                 {$match:{sum_quantity:{$gt:10}}

                 }

        ]

)


结果:


2

源数据:

聚合查询如下:

db.student.aggregate([{

         $lookup: {

                  from: "class",

                  localField: "class_id",

                  foreignField: "id",

                 as: "class_info"

          }

},

         {$unwind:"$class_info"},

         {$project:{"class_info._id":0,"class_info.id":0}},

         {$match:{age:{$gte:16}}},

         {$sort:{age:1}}

]).pretty();


结果:


五、聚合查询在日常运维中的使用


Mongodb中除少量配置集合外,无相关的性能视图。早期版本只有db.currentOp()命令可查看会话信息,从3.6版开始提供$currentOpstage,可更加灵活的获取会话信息。

$currentOpstage只能在admin库执行

{$currentOp: { allUsers: , idleConnections: } }


--显示当前的会话中,以客户端IP地址分组统计连接数

useadmin

db.aggregate([

{$currentOp: { allUsers: true ,idleConnections:true} },

{$project:{IP:{$split:["$client",":"]}}},

{$project:{IP:{$split:["$client",":"]}}},

{$unwind:"$IP"},

{$match:{"IP":/^10./}},

{$group:{_id:"$IP",count:{$sum:1}}}

]);


--查看当前活动会话正在执行的操作

useadmin

db.aggregate([

{$currentOp: { allUsers: true ,idleConnections:false} },

{$project:{opid:1,client:1,op:1,ns:1,microsecs_running:1,command:1}},

{$match:{client:{$exists:true}}},

{$sort:{microsecs_running:-1}}

]).pretty();



---检查是否有会话在等待锁

db.aggregate([

          {$currentOp: { allUsers: true ,idleConnections:false} },

{$project:{opid:1,client:1,op:1,ns:1,microsecs_running:1,waitingForLock:1}},

          {$match:{"waitingForLock":true}},

          {$count:"waitfor locks"}

          ]);


如果存在大量锁等待,则首先检查是否存在表、库、全局锁

db.aggregate([

          {$currentOp: { allUsers: true ,idleConnections:false} }, 

  {$match:{$or:[{"locks.Global":"W"},{"locks.Database":"W"},{"locks.Collection":"W"}]}}

           ])

如果发现有会话持有表级、库级或者全局锁,则可根据其opid,执行db.killOp(opid)释放锁资源。如果未发现表级以上的锁,则检查不处于等待状态的会话在做些什么操作,再进行具体处理


$collStats返回表的统计信息,其信息比db.collection.status()详细,提供访问的ops时长信息。
 $indexStatus 返回索引统计信息,可返回索引的访问次数,可用在数据治理中。

--结合js脚本,输出某个库中从未使用过的索引(输出json)

db.getCollectionNames().forEach(function(collection){

if(db[collection].getIndexes().length != 1) {

print("Indexesfor " + collection + ":");

db[collection].aggregate([{

$indexStats:{}

},{

$project:{

host:0

}

}]).forEach(

function(opDoc){

if(opDoc.accesses.ops == 0 && opDoc.name != "_id_") {

printjson(opDoc);

}

});

}

});


END



文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/129983.html

相关文章

  • 一文梳理 RedHat 和 CentOS 维中网络知识

    摘要:一系统运维中网络方面的规划与思考在很多公司,岗位职责都是很明确的,专职转岗,每人或者每组负责一块业务。二系统运维中网络方面操作梳理在系统运维中,经常涉及的网络方面的操作,一般由以下几个方面组成。初步意见,交换机上线这台机器所连端口。运维是一门艺术,也是一门苦差事,每个人对此均有不同的理解,正所谓一千个人眼中有一千个哈姆雷特。干一行就要爱一行,既然选择了这个行业,较好是能把它做到较好,发挥自己...

    Olivia 评论0 收藏0

发表评论

0条评论

IT那活儿

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<