db.user.count({"i":{"$gt":NumberInt("5700")}}); # 根据条件查询并count
db.runCommand({"distinct":"user","key":"age"}); # 查询user集合中不同年龄的总数,相当于group的数据,但是不能得到其他列
跟mysql中的group by非常的类似,比如有一大堆订单数据,根据每天字段进行分组,获取每天商品的最高价格,则可以使用下列方式,使用语法如下:
db.runCommand({"group":{
"ns" : "user", # user为集合的名称,等价于 db.user.group({...});
"key" : {"user-group-field" : true} , # key指定集合中需要被分组的字段
"initail" : {"return-field" : {} }, # initail为需要返回的字段和初始值 初始只可以为{},"", 0 等
"reduce": function(curr, old) { # reduce函数,之前的文档和现在的文档进行比较
if(curr.price > old.price) {
// 进行替换操作,则会将最大的结果值
}
}
"finalize": function(old) {
# 对返回的结果再次进行过滤等,
}
"condition":{ ...} # condition中为查询条件,如只查询最近半年的数据等
}});
MongoDB的聚合框架,需要先创建一个管道(pipeline),然后按照需求进行以下构建的组合(指定的先后顺序,可多次使用同一操作),并返回需要的结果集。构建包括:筛选(filtering)、投射(projecting)、分组(grouping)、排序(sorting)、限制(limiting)、跳过(skiping)。语法如下:
db.user.aggregate({ 安装顺序的构建组件 });
{"$project":{"username":1, "age":0}} # 指定username是需要查询返回的字段,设置别名等,而age则不需要返回
{"$group":{"_id":"username","count":{"$sum":1}}} # 当集合中分组字段username出现一次则sum数加1,红色为固定格式
{"$sort":{"username":-1,"age":1}} # 将username字段进行倒序,年龄进行正序
{"$limit":10000} # limit数,能想象$skip也一样
可以理解为聚合之前的查询操作,过滤掉不需要的文档,可以使用等于、大于、小于、in等操作,并且应该尽量放在最前面,以过滤掉做的的内容,并且尽量使用索引;但是不能在其中使用地理位置操作符,语法如:
{"$match":{"age":{"$gte":NumberInt("18")}}}; # 聚合前查询年龄大于等于18的文档
将文档中的数组提升为父级结果返回,例如像查询满足某一条件的多个文档中的数组中的数据进行返回,返回的时候不想再按照文档维度进行返回,而言返回一个上一级的列表
{"$unwind":"comments"} # 将评论字段按照非文档维度,而是评论维度进行返回
上面讲的是集中比较简单的使用语法,而很多时候使用的情况会很复杂,则需要对返回字段和分组进行专门的研究。
{"$project":{"name":"$username","username":1}} # 使用$字段名,为该字段取别名为name
$add db.user.aggragate({"$project":{"totalMoney":{"$add":["$field1","$field2","$field3"]}}}); # 将多个字段的值相加
$subtract db.user.aggragate({"$project":{"totalMoney":{"$subtract":["$field1","$field2"]}}}); # 两个字段相减
$multiply db.user.aggragate({"$project":{"totalMoney":{"$multiply":["$field1","$field2","$field3"]}}}); # 多个字段相乘
$divide db.user.aggragate({"$project":{"totalMoney":{"$divide":["$field1","$field2","$field3"]}}}); # 两个字段相除
$mod db.user.aggragate({"$project":{"totalMoney":{"$mod":["$field1","$field2"]}}}); # 两个字段做余数
很多时候需要安装日期对数据进行聚合,特别是在做统计的时候,数据库使用日期聚合框架统计数据,而前端使用图表进行展示。语法如下(前提是只能对日期字段做聚合,包括日期的数字字段):
# month为返回的名称,$month为聚合的日期表达式,而date-field为集合中的日期字段,使用时在前面加上$符号
db.user.aggregate({"$project":{"month":{"$month":"$date-field"}}});
常用的日期表达式有:
$month
$year
$week
$dayOfMonth
$dayOfWeek
$dayOfYear
$hour
$minute
$second
$substr
db.user.aggregate({"$project":{"field-return":{"$substr":{"$str",0,5}}}}); # 将str字段取子字符串,并作为field-return名称返回
$concat
db.user.aggregate({"$project":{"field-return":{"$concat":["$field-1","$field-2","$field-3"...]}}});
$toLower
$toUpper
逻辑判断相关的表达式,语法如下:
db.user.aggregate({"$project":{"return-name":{"$cmp":["expr1","expr2"]}}});
$cmp
如果exp1等于exp2则返回0,exp1 $strccasecmp 与上面相同,只是区分大小写 $eq、$ne、$gt、$gte、$lt、$lte expr1与exrp2进行比较,返回true或者false $and expr1、expr2、... 多个值的and操作,返回true或者false(都为true才true) $or expr1、expr2、... 多个值的or操作,返回true或者false(一false则false) $not 对后面的操作进行取反 $cond 后面跟三个对象的数组,第一个为boolean,后两个为需要返回的表达式,即三元表达式 $ifNull 后面跟两个表达式的数组,if为null则返回后者,否则返回前表达式 $sum {"$group":{"_id":"username","count":{"$sum":1}}} # 当集合中分组字段username出现一次则sum数加1,红色为固定格式 $avg 语法同是,只是进行平均数计算 $max 返回分组内的最大值 $min 返回分组内的最小值 $first 返回分组的第一个值,但是只要排序后才有意义,否则第一个可能是随机的 $last 同上,但是返回最后一个值 $addToSet 当数组中不存在则将其添加到数组中,在返回的结果集中只出现一次,并在是无序的 $push 不管数组中是否有表达式的值,都将其添加的数组中 3、$group
1)、$group算术操作符
2)、$group极值操作符
3)、数组操作符