我们先来看几个简单的聚合命令:

1.count

> db.foo.count()
4
> db.foo.find({_id:{$gte:2}})
{ "_id" : 2, "x" : 2 }
{ "_id" : 3, "x" : 3 }
> db.foo.find({_id:{$gte:2}}).count()
2
> db.foo.count({_id:{$gte:2}})
2
>

这个命令很简单,但我们往往会忽略 最后一种用法,其实count() 函数里面也可以加条件的。

类似于sql 的:  select count(*) from table_name;

2.distinct

> db.order_detail.find()
{ "_id" : 1, "cust_id" : 1, "order_id" : 1, "prod_id" : 1 }
{ "_id" : 2, "cust_id" : 1, "order_id" : 1, "prod_id" : 2 }
{ "_id" : 3, "cust_id" : 2, "order_id" : 2, "prod_id" : 2 }
{ "_id" : 4, "cust_id" : 3, "order_id" : 2, "prod_id" : 1 }
{ "_id" : 5, "cust_id" : 3, "order_id" : 3, "prod_id" : 3 }

示例数据如上。如果我们要查询 有多少种prod_id

db.runCommand({distinct:"order_detail",key:"prod_id"})
{"values" : [1,2,3],"stats" : {"n" : 5,"nscanned" : 5,"nscannedObjects" : 5,"timems" : 0,"cursor" : "BasicCursor"},"ok" : 1
}

功能类似于sql : select distinct prod_id from table_name

3.GROUP

我们再来先看示例:

> db.runCommand({group:{ "ns":"order_detail",
... key:{cust_id:true},
... initial:{"qty":0},
... "$reduce":function(doc,prev){
... prev.qty +=1; }
... } } )
{"retval" : [ {"cust_id" : 1,"qty" : 2},{"cust_id" : 2,"qty" : 1},{"cust_id" : 3,"qty" : 2}],"count" : 5,"keys" : 3,"ok" : 1
}

关键词说明:

ns: 要分组的集合

Key :分组依据的键

Initial:初始化

Reduce: reduce 函数

sort: 排序依据;

使用GROUP 可以求:

Count   计数;

SUM  和

AVG  平均值

MAX  最大值

MIN  最小值

FIRST  第一个值

LAST  最后一个值

如果指定了排序键值,那么使用 $first / $last 性能会比 MAX/ MIN 好。但在使用$FIRST/$ LAST  时,$sort 放在 $FIRST/$ LAST  前面

以下是一个书上的例子:

按日期分组,列出每天最后交易时间及价格

> db.runCommand({"group" : {
... "ns" : "stocks",
... "key" : "day",
... "initial" : {"time" : 0},
... "$reduce" : function(doc, prev) {
...     if (doc.time > prev.time) {
...         prev.price = doc.price;
...         prev.time = doc.time;
...     }
... }}})
db.scores.aggregate(
... {
...     "$sort" : {"score" : 1}
... },
... {
...     "$group" : {
...         "_id" : "$grade",
...         "lowestScore" : {"$first" : "$score"},
...         "highestScore" : {"$last" : "$score"}
...     }
... })

当然,在group 中,你也可以使用  $LIMIT,$SKIP ,同时也可以添加条件进行汇总查询。

$condition  添加查询条件

> db.order_detail.find()
{ "_id" : 1, "cust_id" : 1, "order_dt" : ISODate("2014-04-30T16:00:00Z"), "order_id" : 1, "prod_id" : 1 }
{ "_id" : 2, "cust_id" : 1, "order_dt" : ISODate("2014-08-11T05:45:50.584Z"), "order_id" : 1, "prod_id" : 2 }
{ "_id" : 3, "cust_id" : 2, "order_dt" : ISODate("2014-08-11T05:45:50.584Z"), "order_id" : 2, "prod_id" : 2 }
{ "_id" : 4, "cust_id" : 3, "order_dt" : ISODate("2014-08-11T05:45:50.584Z"), "order_id" : 2, "prod_id" : 1 }
{ "_id" : 5, "cust_id" : 3, "order_dt" : ISODate("2014-08-11T05:45:50.584Z"), "order_id" : 3, "prod_id" : 3 }
> db.runCommand({group:{ "ns":"order_detail",
... key:{cust_id:true},
... initial:{"qty":0},
... "$reduce":function(doc,prev){
... prev.qty +=1; } ,
... condition:{order_dt:{$gt:new Date('2014,08,01')}}
... } } )
{"retval" : [{"cust_id" : 1,"qty" : 1},{"cust_id" : 2,"qty" : 1},{"cust_id" : 3,"qty" : 2}],"count" : 4,"keys" : 3,"ok" : 1
}
>

Condition  也可以简写成 cond, 或:query ,q

4.Aggregate()

还是先看示例:

> db.order_detail.aggregate( {$group:{_id:"$cust_id",count:{$sum:1}}} )
{"result" : [{"_id" : 3,"count" : 2},{"_id" : 2,    "count" : 1},{"_id" : 1,    "count" : 2}],"ok" : 1
}
>

aggregate() 聚合函数功能就强大了:

关键词如下:

{$project:{“author”:1}} 指定要显示的字段名称

{$match:{“state”:”OR”}} 指定查询的条件

{$group:{_id:”$day”}} 指定分组的字段

{$sort:{count:-1}} 指定排序

{$limit:5} 指定返回的数量 ,当然也可以使用 $skip

{unwind:”$comments”} 指定拆分的字段  (独立使用)

4.1 这里主要来讲讲 $project :

在sql 中,我们有 substr(col1,1,10), to_str(create_dt,'yyyy') ,此类的功能,只取字段的某一部分。在MONGODB 中,我们也可以实现。

这就是我们这里要讲的。

a. 指定某些字段要显示: {$project:{"userId":"$_id","_id":0}}

b.字符串处理:

"$substr":{$substr:[col1,1,10]}  ,类似于 substring(col1,1,10)

“$concat”:{"$concat":[col1,col2]}, 类似于 col1+col2

"$toLower":{"$toLower:col1"}     ,类似于 lower(col1)

"$toUpper":{"$toLower:col1"}

b.日期处理:

"$year","$month”,"$week","$dayOfMonth","$dayOfweek","$dayOfYear","$hour","$minuse","$second" ,使用这些函数,可以返回你所需要的一个日期字段的部分值。

c.数字计算:

“$add” + ,"subtract" - ,'$multiply' *,'$divide' /,"$mod" 取余。这些计算操作符,可以把多个字段的计算后返回。

d.逻辑表达式:

还可以进行逻辑处理,返回一个新的字段值:

“$cmp”: [expr1,expr2]

expr1=expr2: 0;

expr1<expr2: 负数;

expr1>expr2: 正数;

“$strcasecmp”:[str1,str2]

区分str1,str2 大小

"$and":[expr1,expr2]

所有条件为true,返回 true,否则false;

"$or":[expr1,expr2]

只要有一条件为true,返回 true,否则false;

"$not":expr1

取反

"$cond":[booleanExpr: trueExpr,falseExpr]

如果 booleanExpr=true,返回trueExpr ,否则返回 falseExpr

"$ifNull":[expr,replacementExpr] 类似于: oracle: nvl()

4.2 多重分组

先看一个官方的示例:

db.zipcodes.aggregate( [{ $group : { _id : { state : "$state", city : "$city" }, pop : { $sum : "$pop" } } },{ $group : { _id : "$_id.state", avgCityPop : { $avg : "$pop" } } }
] )

在aggregate 中,可以使用多重组合。也就是使用前一个分组后的数据,再进行一次分组。

比如下面的sql:

select ip.city,count(distince user_cookie) from website_open_log

group by ip.city

我要统计网站的登录用户的分布。但汇总的数据为有多人人,而不是有多少次。同一个用户可能有多次访问。

下面的代码中,我使用了两种方法,统计结果稍有些不同,但在这里很能说明问题

db.website_open_log.aggregate({$match:{company_id:1}},{$group:{_id:"$cookie",ip:{$first:"$ip.province"}}},{$group:{_id:"$ip",qty:{$sum:1}}},{$sort:{qty:-1}},{$limit:10})
> db.website_open_log.aggregate({$match:{company_id:1}},
...  {$group:{_id:{"cookie":"$cookie","province":"$ip.province"},
...           qty:{$sum:1}
...   }
...  },
...  {$group:{_id:"$_id.province",
...           qty1:{$sum:1}
...   }
...  },
...  {$sort:{qty1:-1}}
...  );

【知识小课堂】 之 聚合函数相关推荐

  1. 【知识小课堂】 mongodb 之 objectId

    一.OBJECTID 因公司开发人员在使用MONGODB时,总遇到一些小问题.为了增加大家的mongodb 数据库知识. 决定每周进行一.两次的知识小课堂.这里把内容整理出来,上传到博客中.也算是自己 ...

  2. 宝付国际跨境知识小课堂 | 人民币外汇市场是个啥?

    全球化浪潮下,因为各个经济体的比较利益差异,产生了货物.服务.人员或资本之间的流动.各个经济体使用的当地货币不同,为了贸易或资本流动及其价值定价,本国的货币需要兑换成另一国的货币来结算,这个货币兑换的 ...

  3. 计算机知识小课堂宣传标语,创建高效课堂宣传标语50条

    创建高效课堂宣传标语50条 在日常学习.工作或生活中,大家都接触过很多优秀的标语吧,标语是指文字简练.意义鲜明的宣传.鼓动口号.那什么样的标语才算得上是经典呢?以下是小编精心整理的创建高效课堂宣传标语 ...

  4. 家电知识小课堂 帮您避过选购的那些坑

    本文来自IT168 大家在选购家电时,是否会或多或少拥有一些困惑呢?面对琳琅满目的众多产品,不知道该如何选择,甚至一不小心就可能陷入某些选购陷阱之中,多花了冤枉钱.下面我们就来为大家普及一些家电选购的 ...

  5. 模具制造设计知识小课堂

    "潇洒模具"--模具制造设计培训讲堂: 一,选择模具钢时什么是最重要的和最具有决定性意义的因素? 成形方法:可从两种基本材料类型中选择. A) 热加工工具钢,它能承受模铸.锻造和挤 ...

  6. 【知识小课堂】mongodb 之 特殊集合及索引

    1.固定集合 一般的集合都是动态的,可以自动增长以容纳越来越多的数据. 但MONGODB 还有另外一种集合:固定集合.集合大小创建时指定.如果没有空间了,就会自动删除最老的文档,以释放空间.(类似以一 ...

  7. 【知识小课堂】4 之 索引

    索引类型 mongoDB 的索引在存储结构都是一样的,但是根据不同的应用需求,还是分成了:唯一索引,稀疏索引,复合索引 1.唯一索引 MONGODB 在默认建立文档时,都会自动添加一个:"_ ...

  8. 【知识小课堂】mongodb 之 查询关键词使用

    查询关键词: $or 多个条件 满足其中一个 即可: Syntax:{ $or: [ { <expression1> }, { <expression2> }, ... , { ...

  9. 【知识小课堂】 mongodb 之字段中的【 数组】、【内嵌文档】

    一.介绍 MONGODB 的表结构 很灵活 .主要还是因为 字段中可以包含 [ 数组].[内嵌文档]. 现在简单介绍一下 字段中的[ 数组].[内嵌文档]相关的一些操作 (为了方便理解,还是以表来理解 ...

最新文章

  1. 嫌弃YouTube推荐算法,这位小哥决定自己动手写代码来推荐视频
  2. VS2013无法启动IIS Express Web的解决办法
  3. 《移山之道》第十一章:两人合作 读书笔记 PB16110698 第六周(~4.15)
  4. 一种推理优化新思路,对特征图进行[随机采样-插值]
  5. vue 地图使用navigator_weex踩坑之旅第五弹 ~ 使用navigator内置模块实现导航
  6. php的对象和数组应该学js,JavaScript数组与对象的常用方法及 json 的序列化
  7. 什么是延展性(Malleability,可鍛性)
  8. 多用户文件系统java实现_小师妹学JavaIO之:文件系统和WatchService
  9. C语言之浅析网络包解析
  10. Linux离线安装gcc
  11. win7资源服务器未响应,win7电脑怎么设置服务器未响应
  12. 相关系数(Correlation coefficient)
  13. 100条历史典故,读懂半个中国
  14. 视频教程-JavaSE基础视频精讲⑰:IO流高级用法-Java
  15. excel-中心趋势-基本函数-离散程度-四分位数QUARTILE.EXC-画箱线图-标准差
  16. 曾经沧海难为水,除却巫山不是云。
  17. java案例_面向对象编程_Stool
  18. 天梯赛:L2-039 清点代码库 (25 分)
  19. PHP随机生成英文大小写
  20. 【AAAI 2021】跨层知识蒸馏:Cross-Layer Distillation with Semantic Calibration

热门文章

  1. Codeforces 1209D Cow and Snacks
  2. 排序算法以及其java实现
  3. 手写的奇怪vector
  4. (golang)HTTP基本认证机制及使用gocolly登录爬取
  5. SQL Server 2008如何创建定期自动备份任务
  6. [centos][ntp][administrator] chrony ntp
  7. nth-of-type(n)
  8. Spring学习(一)初识Spring
  9. Linux设置Oracle开机自启动
  10. struts2中访问servlet API