MongoDB除了基本的查询功能,还提供了很多强大的聚合工具,其中简单的可计算集合中的文档个数,

复杂的可利用MapReduce做复杂数据分析.

1.count

count返回集合中的文档数量

db.refactor.count()

不管集合有多大,都能很快的返回文档数量.

可以传递查询,MongoDB会计算查询结果的数量

db.refactor.count({"username":"refactor"})

但是增加查询条件会使count变慢.

2.distinct

distinct用来找出给定键的所有不同值.使用时必须指定集合和键.

如:

db.runCommand({"distinct":"refactor","key":"username"})

3.group

group先选定分组所依据的键,MongoDB将会将集合依据选定键值的不同分成若干组.然后可以通过聚合每一组内的文档,

产生一个结果文档.

如:

db.runCommand(
{
  "group":
  {
    "ns":"refactor",
    "key":{"username":true},
    "initial":{"count":0},
    "$reduce":function(doc,prev)
    {
      prev.count++;
    },
    "condition":{"age":{"$gt":40}}
  }
}
)

"ns":"refactor",

指定要进行分组的集合
    "key":{"username":true},

指定文档分组的依据,这里是username键,所有username键的值相等的被划分到一组,true为返回键username的值
    "initial":{"count":0},

每一组reduce函数调用的初始个数.每一组的所有成员都会使用这个累加器.
    "$reduce":function(doc,prev){...}

每个文档都对应的调用一次.系统会传递两个参数:当前文档和累加器文档.

"condition":{"age":{"$gt":40}}

这个age的值大于40的条件

4.使用完成器

完成器用于精简从数据库传到用户的数据.group命令的输出一定要能放在单个数据库相应中.

"finalize"附带一个函数,在数组结果传递到客户端之前被调用一次.

db.runCommand(
  {
    "group":
    {
      "ns":"refactor",
      "key":{"username":true},
      "initial":{"count":0},
      "$reduce":function(doc,prev)
      {
        prev.count++;
      },
      "finalize":function(doc)
      {
        doc.num=doc.count;
        delete doc.count;
      }
    }
  }
)

finalize能修改传递的参数也能返回新值.

5.将数组作为键使用

有些时候分组所依据的条件很复杂,不仅是一个键.比如要使用group计算每个类别有多篇博客文章.由于有很多作者,

给文章分类时可能不规律的使用了大小写.所以,如果要是按类别名来分组,最后"MongoDB"和"mongodb"就是不同的组.

为了消除这种大小写的影响,就要定义一个函数来确定文档所依据的键.

定义分组要用到$keyf

db.runCommand(
 {
  "group":
   {
    "ns":"refactor",
    "$keyf":function(doc){return {"username":doc.username.toLowerCase()}},
    "initial":{"count":0},
    "$reduce":function(doc,prev)
       {
        prev.count++;
       }
   }
 }
)

6.MapReduce

count,distinct,group能做的事情MapReduce都能做.它是一个可以轻松并行化到多个服务器的聚合方法.它会

拆分问题,再将各个部分发送到不同机器上,让每台机器完成一部分.当所有机器都完成时候,再把结果汇集起来形成

最终完整的结果.

MapReduce需要几个步骤:

1.映射,将操作映射到集合中的每个文档.这个操作要么什么都不做,要么 产生一个键和n个值.

2.洗牌,按照键分组,并将产生的键值组成列表放到对应键中.

3.化简,把列表中的值 化简 成一个单值,这个值被返回.

4.重新洗牌,直到每个键的列表只有一个值为止,这个值就是最终结果.

MapReduce的速度比group慢,group也很慢.在应用程序中,最好不要用MapReduce,可以在后台运行MapReduce

创建一个保存结果的集合,可以对这个集合进行实时查询.

找出集合中的所有键

MongoDB没有模式,所以并不知晓每个文档有多少个键.通常找到集合的所有键的做好方式是用MapReduce.

在映射阶段,想得到文档中的每个键.map函数使用emit 返回要处理的值.emit会给MapReduce一个键和一个值.

这里用emit将文档某个键的记数(count)返回({count:1}).我们为每个键单独记数,所以为文档中的每一个键调用一次emit,

this是当前文档的引用:

map=function(){
  for(var key in this)
  {
    emit(key,{count:1})
  }
};

这样返回了许许多多的{count:1}文档,每一个都与集合中的一个键相关.这种有一个或多个{count:1}文档组成的数组,

会传递给reduce函数.reduce函数有两个参数,一个是key,也就是emit返回的第一个值,另一个参数是数组,由一个或者多个

对应键的{count:1}文档组成.

reduce=function(key,emits){
  total=0;
  for(var i in emits){
    total+=emits[i].count; 
  }
  return {count:total};
}

reduce要能被反复被调用,不论是映射环节还是前一个化简环节.reduce返回的文档必须能作为reduce的

第二个参数的一个元素.如x键映射到了3个文档{"count":1,id:1},{"count":1,id:2},{"count":1,id:3}

其中id键用于区别.MongoDB可能这样调用reduce:

>r1=reduce("x",[{"count":1,id:1},{"count":1,id:2}])

{count:2}

>r2=reduce("x",[{"count":1,id:3}])

{count:1}

>reduce("x",[r1,r2])

{count:3}

reduce应该能处理emit文档和其他reduce结果的各种集合.

如:

mr=db.runCommand(
  {
  "mapreduce":"refactor",
  "map":map,
  "reduce":reduce,
  "out":{inline:1}
  }
)

或:

db.refactor.mapReduce(map,reduce,{out:{inline:1}})

"timeMillis" : 5,//操作花费的时间
"counts" : {
"input" : 10,//发往到map函数的文档个数
"emit" : 40,//在map函数中emit被调用的次数
"reduce" : 4,//在map函数中reduce被调用的次数
"output" : 4//结果集合中创建的文档数量.
},

1.mapreduce是根据map函数里调用的emit函数的第一个参数来进行分组的
2.仅当根据分组键分组后一个键匹配多个文档,才会将key和文档集合交由reduce函数处理

注意MongoDB 1.8版本以上,必须指明 out 参数

否则会报如下错误:

"assertion" : "'out' has to be a string or an object",
"assertionCode" : 13606,

MapReduce中的其他键

mapreduce,map,reduce这三个键是必须的,MapReduce命令还有其他的可选键

finalize:函数

将reduce的结果发送给这个键,这是处理过程的最后一步

keeptemp:布尔值

连接关闭时,临时结果是否保存

output:字符串

结果集合的名字,设定该项则隐含着keeptemp:true

query:文档

会在发往map函数前,先用指定条件过滤文档

sort:文档

会在发往map函数前先给文档排序

limit:整数

发往map函数文档的最大数量

scope:文档

javascript代码中要用到的变量

verbose:布尔值

是否产生更加信息的服务器日志

MongoDB 聚合 (转) 仅限于C++开发的更多相关文章

  1. MongoDB 查询 (转) 仅限于C++开发

    1.find MongoDB使用find来进行查询.查询就是返回一个集合中文档的子集,子集合的范围从0个文档到整个集合.find的第一个参数 决定了要返回哪些文档.其形式也是一个文档,说明要查询的细节 ...

  2. MongoDB 聚合分组取第一条记录的案例及实现

    关键字:MongoDB: aggregate:forEach 今天开发同学向我们提了一个紧急的需求,从集合mt_resources_access_log中,根据字段refererDomain分组,取分 ...

  3. SWF 文件不能本地访问 只有仅限于文件系统的 SWF 文件

    http://blog.163.com/vituk93@126/blog/static/1709580342012512112757505/ SWF 文件不能被本地访问 不能访问本地 只有仅限于文件系 ...

  4. MongoDB 聚合管道(Aggregation Pipeline)

    管道概念 POSIX多线程的使用方式中, 有一种很重要的方式-----流水线(亦称为"管道")方式,"数据元素"流串行地被一组线程按顺序执行.它的使用架构可参考 ...

  5. Mongodb学习笔记四(Mongodb聚合函数)

    第四章 Mongodb聚合函数 插入 测试数据 ;j<;j++){ for(var i=1;i<3;i++){ var person={ Name:"jack"+i, ...

  6. ORA-00257: 归档程序错误。在释放之前仅限于内部连接

    今天发现oracle数据库连不上,报错:ORA-00257: 归档程序错误.在释放之前仅限于内部连接 马上联想到可能是空间满了,一看磁盘目录,果然. 解决方法如下: 1:查看归档日志目录. 登陆账号后 ...

  7. mongodb MongoDB 聚合 group

    MongoDB 聚合 MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果.有点类似sql语句中的 count(*). 基本语法为:db.col ...

  8. MongoDB 聚合

    聚合操作过程中的数据记录和计算结果返回.聚合操作分组值从多个文档,并可以执行各种操作,分组数据返回单个结果.在SQL COUNT(*)和group by 相当于MongoDB的聚集. aggregat ...

  9. Struts 2.x仍然明显落后于时代。 Struts 2.x这一类老牌Web MVC开发框架仅能用于开发瘦客户端应用,无法用来开发对于交互体验要求更高的应用。

    后来我在工作中陆续使用过Struts 1.x和Struts 2.x.我曾经把一个开源的基于Struts 1.x的自助式广告联盟应用移植到Spring MVC,还基于Struts 2.x做过网站开发.S ...

随机推荐

  1. DirectX小记

    1.关于SetViewPort 如果不调用SetViewPort,那么设备对应的ViewPort是什么. 2.关于多线程渲染 如果逻辑线程和渲染线程分开, 则存在两种渲染方式 a.逻辑线程一次性提交渲 ...

  2. Growing转化的每一步(笔记整理)

    渠道流量监控中,如何将劣质流量和优质流量区分开来? 劣质流量总会有有一些不同于其他正常渠道的特征,比如在同一个时间中大量集中访问.使用的硬件设备比较固定.使用特定的浏览器等. 实际案例:去年有一些 A ...

  3. VBA提高速度的技巧

    此贴原转自EH论坛,我自己有所修改 [编者按]速度是程序设计永恒的热门话题,虽然速度技巧在各种语言之间可以相互借鉴,但差别有时也会很大,比如VC中由于字符串的存储方式决定了判断空串使用len函数更快, ...

  4. mouseenter和mouseout中间的时间控制

    为了防止鼠标快速滑过div而加的时间限制: 在看延迟绑定时候看到,这也算是延迟绑定了?:(20130909) <!DOCTYPE html> <html lang="en& ...

  5. ubuntu环境变量添加变量

    1.sudo gedit /etc/profile打开环境变量文件夹 2.在文件末尾另起一行输入要加入的环境变量 格式: export XXXXXX=XXXXXX 3.重启 OK

  6. linux----关于定位和查找

    1.top --查看进程2.su --临时切换用户命令[root@tomato2 ~]# sudo su gongxijun[gongxijun@tomato2 root]$ 3.whoami --- ...

  7. 学习HTML5之塔克大战(详细记录)

    学了一些HTML5的一些基本知识,开始学习制作...... 介绍一些基本知识:  px(像素)--->1px等于多少? 1cm or 2cm -->no  no no! (1).像素是一个 ...

  8. Path Sum [LeetCode]

    Problem Description: http://oj.leetcode.com/problems/path-sum/ Pretty easy. /** * Definition for bin ...

  9. easyUI dialog 弹窗 居中显示

    默认情况下应该是在屏幕居中显示的.但是有的时候没有居中只要重新纠正下就可以了 $('#add_dialog').dialog('open'); //打开添加对话框 $('#add_dialog').w ...

  10. Generic泛型

    1.问题 未使用泛型时,元素的类型不安全:操作麻烦,可能需要强制转换import java.util.ArrayList;import java.util.List;import org.junit. ...