聚合框架
使用聚合框架可以对集合文档进行变换和组合等,是通过一个或者多个管道操作符对一连串的文档进行处理;例如db.DB_COLLECTION.aggregate({"$project":{"name":1}}, {"group": {"_id":"name", "count":{"$sum":1}}})
,这里用了2个管道操作符;
- aggregate()会返回一个文档数组
- 第一个管道操作符返回的结果集作为第二个管道操作符的输入;
- 聚合结果集不能过大,限制在16MB内;
管道操作符
每个管道操作符都会接受一连串文档,前一个操作符转换后的文档传递给下一个操作符,最后一个操作符的结果集返回给客户端;另外,不同的管道操作符可以按照任何顺序组合在一起使用,而且可以重复使用多次;
下面介绍下各个管道操作符。
$match
筛选操作符
用于对文档集合进行筛选,可以在筛选得到的文档子集上做聚合。例如{$match:{"age":20}}
筛选age为20的文档。
$match
可以使用常规的查询操作符,例如$gt
、$in
等,但是不能使用地理空间操作符$match
应该放在管道的最前位置,一是可以快速将不需要的文档过滤掉;二是可以使用集合已有的索引;
$project
投射操作符
管道中的投射操作十分强大,使用$project
可以从子文档提取字段、可以重命名字段、可以对字段使用表达式操作等;
-
$project
用于提取字段时语法跟普通查询时的第二个参数类似;例如返回结果需要"author"不需要"_id":{"$project":{"author":1,"_id":0}}
-
$project
用于对字段重命名的语法{“KaTeX parse error: Expected '}', got 'EOF' at end of input: …":{"new_name":"old_name”}},例如把"_id"重名为"_useId"为{"KaTeX parse error: Expected '}', got 'EOF' at end of input: …ct":{"_useId":"_id"}};注意事项:- 字段重命名后,不能使用原名字创建的索引了,使用尽量在修改字段名称前使用索引;
-
使用表达式将多个字面量和变量组合在一个值中使用
- 数学表达式
$add
加法、$subtract
减法、$multiply
乘法、$divide
除法、$mod
求余,例如获取奖励+薪资的总和:db.DB_COLLECTION.aggregate( { "$project":{ "totalPay":{"$add":["$salary", "$bonus"]} } } )
- 日期表达式
$year
、$month
、$hour
等等,需要注意的是只能对日期类型的字段进行日期操作; - 另外还有字符存表达式(例如
$substr
截取子串、$concat
连接、$toLower
转小写等)和逻辑表达式(例如$cmd
比较、$and
与操作等等);
- 数学表达式
$group
分组操作符
$group
可以对多个字段进行进行分组,选定了需要分组的字段后就可以将选定的字段传递给"KaTeX parse error: Expected '}', got 'EOF' at end of input: …"和城市名"city",`{"group":{"_id":{“state”:“
s
t
a
t
e
"
,
"
c
i
t
y
"
:
"
state", "city":"
state","city":"city”}}}`;
另外,支持使用分组操作符对每个分组中的文档做一些计算:
- 算术操作符,
$sum
求和、$avg
平均数,例如求每个国家的总收入和平均收入db.DB_COLLECTION.aggregate( { "$group":{ "_id":"$country", "totalRevenue":{"$sum":"$revenue"}, "avgRevenue":{"$avg":"$revenue"} } } )
- 极限操作符,
$max
分组最大值、$min
分组最小值、$first
分组第一个值、$last
分组最后一个值; - 分组操作符不能使用流式工作方式对文档进行处理,即
$group
必须要等收到所有文档后才能进行操作;
$unwind
拆分操作符
$unwind
可以将数组中每一个值拆分为单独的文档,例如将博客的每条评论拆分为一个独立的文档db.DB_COLLECTION.aggregate({"$unwind": "$comments"})
;
其他管道操作符
$sort
排序操作符;$limit
返回结果集中前n个文档的操作符;$skip
跳过结果集中前n个文档的操作符,跟普通查询一样,skip如果跳过大量数据效率非常低;