设为首页 收藏本站
查看: 1972|回复: 0

[经验分享] MongoDB:详细解释mongodb的高级操作,聚合和游标

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2013-12-24 09:51:11 | 显示全部楼层 |阅读模式

前几天总结了mongodb的安装入门、详细解释了增删改查的基本操作,今天再来总结下mongodb更高级的操作,聚合和游标。

一、聚合,mongodb的聚合操作一般分为四种情景,分别是:count、distinct、group、mapReduce

1、count

count最简单,最容易,也是我们最常用的聚合工具,话说最常用的大家都会用,所以对大家都不是问题,所以叫最简单~~




  • count  
  • db.person.find()  
  • db.person.count()  
  • db.person.count({"age":40})  

SouthEast.jpg

2、distinct

顾名思义,指定了谁,谁就不能重合。




  • db.person.distinct("age")  


SouthEast.jpg

3、group

group的操作有些小复杂,但是越是复杂的操作,应用起来就越灵活,group的操作本质上相当于一种“key-value”模型。

下面举的例子就是按照age进行group操作,value为对应age的姓名。下面对这些参数介绍一下:

key:  这个就是分组的key,我们这里是对年龄分组。
initial: 每组都分享一个”初始化函数“,特别注意:是每一组,比如这个的age=10的value的list分享一个initial函数,age=40同样也分享一个initial函数。
$reduce: 这个函数的第一个参数是当前的文档对象,第二个参数是上一次function操作的累计对象,第一次为initial中的{”perosn“:[]}。有多少个文档, $reduce就会调用多少次。




  • group  
  •   
  • db.person.group({  
  •     "key":{"age":true},  
  •     "initial":{"person":[]},  
  •     "$reduce":function(cur,prev){  
  •         prev.person.push(cur.name);  
  • }  
  • })  


SouthEast.jpg

上面的结果,有时候我们还可能会有其他的需求,例如:

1、过滤掉age<26岁的成员。

2、有时候person的成员太多,我不可能一一查看,所以我想count一下,这样看起来也比较方便。

这在group是非常容易办到的,因为mongodb有两个可选参数:condition 和finalize

condition 是个过滤条件

finalize 是一个方法,每个文章执行完后,都会触发它,可以在这个方法里面加入count。




  • condition 和 finalize  
  • db.person.group({  
  •     "key":{"age":true},  
  •     "initial":{"person":[]},  
  •     "$reduce":function(cur,prev){  
  •         prev.person.push(cur.name);  
  •     },  
  •     "finalize":function(count){  
  •         out.count=out.person.length;  
  •     },  
  •     "condition":{"age":{$gte:10}}  
  • })  

SouthEast.jpg

4、mapReduce

mapReduce其实是一种编程模型,用在分布式计算中,其中有一个“map”函数,一个”reduce“函数。
1、map:
          这个称为映射函数,里面会调用emit(key,value),集合会按照你指定的key进行映射分组。
2、reduce:
         这个称为简化函数,会对map分组后的数据进行分组简化,注意:在reduce(key,value)中的key就是
emit中的key,vlaue为emit分组后的emit(value)的集合,这里也就是很多{"count":1}的数组。
3、mapReduce:
          这个就是最后执行的函数了,参数为map,reduce和一些可选参数。具体看图可知:





  • mapReduce  
  •   
  • map  
  • function(){  
  •     emit(this.name,{count:1});  
  • }  
  •   
  • reduce  
  • function(key,value){  
  •     var result={count:0};  
  •     for(var i=0;i<value.length;i++){  
  •         result.count += value.count;  
  •     }  
  •     return result;  
  • }  
  •   
  • db.person.mapReduce(map,reduce,{"out":"collection"})  
  • {  
  •     "result":"collection",  
  •     "timeMillis":15,  
  •     "counts":{  
  •         "input":7,  
  •         "emit":7,  
  •         "reduce":3,  
  •         "output":4  
  •     },  
  •     "ok":1,  
  • }  

SouthEast.jpg

从图中我们可以看到如下信息:
       result: "存放的集合名“;
       input:传入文档的个数。
       emit:此函数被调用的次数。
       reduce:此函数被调用的次数。
       output:最后返回文档的个数。


二、游标

mongodb里面的游标有点类似我们说的C#里面延迟执行,比如:
      var list=db.person.find();
    针对这样的操作,list其实并没有获取到person中的文档,而是申明一个“查询结构”,等我们需要的时候通过for或者next()一次性加载过来,然后让游标逐行读取,当我们枚举完了之后,游标销毁,之后我们在通过list获取时,发现没有数据返回了。




  • 游标  
  •   
  • var list = db.person.find();  
  •   
  • list.forEach(function(x){  
  •     print(x.name);  
  • })  

SouthEast.jpg


同时,我们也可以查用分页、排序等查询!

这样可以减少不必要的开销




  • var single=db.person.find().sort({"name":1}).skip(2).limit(2);  


SouthEast.jpg

好啦,聚合和游标基本就这些,如果有不对的地方敬请指正。


下期会写关于mongodb索引的建立等操作



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-12217-1-1.html 上篇帖子: mongodb基础系列—副本集具体搭建以及解说 下篇帖子: MongoDB 模糊查询,及性能测试
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表