1.集合框架
使用聚合框架可以对集合中的文档进行变换和组合。
通过创建一个管道( pipeline ) 来对遗传的文旦进行处理
这些构件包括筛选( filtering ) 投射(project) 分组(grouping) 排序(sorting) 限制(limit)和跳过(skipping)
2.管道操作符
2.1 $match
用于对文档集合进行筛选,之后就可以在筛选得到的文档子集上做聚合。
在实际用途中,应该尽可能将此操作符放在管道之前用 (查询可以使用索引)
2.2 $project
投射 操作 可以从子文档中提取字段 可以重命名字段 还可以在这些字段上进行一些有意思的操作
db.test.aggregate({“project”:{“author”:1,”id”:0}})
个人理解project可以控制文档横向展示的属性 而match可以挑出符合条件的文档来进行操作 一个针对横向 一个针对纵向
重命名字段
>db.test.aggregate({"$project":{"userid":"$_id","_id": 0}})
可以使用这种技术生成字段的多个副本 尽量在修改字段之前使用索引
可以使用表达式将多个字面量和变量组合在一个值中使用
在聚合框架中有几个表达式可用来组合或者进行人以深度的嵌套以便创建复杂的表达式
1.数学表达式
加法
>db.test.aggregate(
{
"$project":{
"totalPay":{
"$add":["salary","bonus"]
}
}
}
使用 subtract进行减法
>db.test.aggregate(
{
"$project":{
"totalPay":{
"subtract":[{$add":["salary","bonus"]},"$401k"] } } }
使用multiply 乘法 使用 divide 除法 结果为商 使用 mod 求余
2.日期表达式
取出日期对象类型的月份
>db.test.aggregate(
{
"$project":{
"hireIn":{"$month":"$hireDate"},
"$subtract":[{"$year":new Date()},"$year":"$hireDate"}]
}
}
}
使用week 取出周 使用year 取出年 使用dayOfMonth dayOfWeek dayOfYear hour minute second
3.字符串表达式
生成j.doe@outlook.com格式的email地址
>db.test.aggregate(
{
"$project":{
"email":{
"$concat":[
{"$substr":["fiestName",0,1]},
".",
"$lastName",
"@outlook.com"
]
}
}
}
4.逻辑表达式
$cmp 比较两个对象 相等返回0 大于返回正数 小于返回负数
$strcasecmp 比较两个字符串 区分大小写
”$cond“ :[booleanExpr,trueExpr,falseExpr]
如果boolean值为true,则返回trueExpr”$ifNull“:[expr,replacementExpr]
如果expr是null 返回replacementExpr,否则返回expr
举个栗子
>db.test.aggregate(
{
"$project":{
"grade":{
"$cond":[
"$teachersPet",//if
100,
{ //else
"$add":[
{"$multiply":[.1,"$attendanceAvg"]},
{"$multiply":[.3,"$quizzAvg"]},
{"$multiply":[.6,"$testAvg"]}
]
}
}
}
}
}
2.3 $group
可以将文档一句特定字段的不同值进行分组
1.分组操作符
允许对每个分组进行计算,得到相应的结果
2.算数操作符
$sum 分组中每出现一个文档 就对计算结果加1
$avg 返回平均值
栗子:
>db.test.aggregate(
{
"$group":{
"_id":{"$country"},
"totalRevenue" : {"$avg":"$revenue"}
}
}
}
3.极值操作符
得到数据集合的边缘值
$max
$min
$first
$last
前两个操作符会查看每个文档 若数据无序 可有效工作 若数据有序 可以使用后两个操作符
4.数组操作符
$addToSet : expr
如果当前数组中不包含expr,就将它添加到数组中$push : expr
不管expr是什么值,都将它添加到数组中 返回包含所有值的数组
分片情况下 group行为会现在每个分片上执行 然后各个分片上的分组结果会被发送到mongos上进行最后的同意分组 剩余的管道工作也都是在mongos(而不是分片)上运行的。
2.4 $unwind
拆分 可以讲数组中的每个值拆分为单独的文档
栗子:
>db.test.aggregate(
{
"$project":{"comments":$comments}
},
{
"$unwind": "$comments"
},
{
"$match":{"comments.author":"Mark"}
},
{
"$project":{"text":1,"date":0}
})
2.5 $sort
排序 值为1(升序) 值为-1(降序)
2.6 $limit
返回结果集中的前n个结果
2.7 $skip
跳过前n个结果 将剩余文档作为结果返回