MongoDB之聚合查询
MongoDB之聚合查询
SQL对比聚合框架
| SQL | 聚合框架操作 | ||
| select * | $project,$group函数 | ||
| from | db.collection.aggregate | ||
| join | $unwind | ||
| where | $match | ||
| group | $group | ||
| having | $match | ||
| limit | $limit,$skip | ||
| order | $sort | ||
| $out将查询的结果输入到指定的集合里面 |
$group函数

当前的$addToSethe$push都是想数组里面添加值,那么他们之间肯定有区别?我们的答案是有的,addToSet添加值的时候一定是唯一的,之前没有的才可以添加。而$push可以添加一些不唯一的,也就是可以重复的。
$sum
1 db.user.aggregate([ 2 { 3 $group:{_id:null,count:{$sum:"$id"}} 4 } 5 ])
所有的平均数、求和、最大、最小他们的目标数据都是数字,我们看到的$id,这个表示文档里id字段的值。
$last和$first
1 db.student.aggregate([ 2 { 3 $match: 4 { 5 "stu_number" : {$regex:/^2013/} 6 } 7 }, 8 { 9 $group:{_id:null,first:{$first:"$stu_number"}} 10 } 11 ])
取出当前结果的第一条,如果last就取出当前结果的最后一条;
$addToSet和$push
1 db.student.aggregate([ 2 { 3 $project: 4 { 5 "stu_number" : 1 6 } 7 }, 8 { 9 $match: 10 { 11 "stu_number" : {$regex:/^2013/} 12 } 13 }, 14 { 15 $group:{_id:null,push:{$push:"$stu_number"}} 16 } 17 ]) 18 将获得的结果压入数组中

push操作可以有重复的
$addToSet

addToSet可以自动去重,他所查询的结果里面没有重复的,全部都是唯一的。这也印证前面说的push可以添加重复的而addToSet只能添加唯一的;
$unwind(将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值)等同于Mysql的join操作
1 db.student.aggregate([ 2 { 3 $match : {"stu_number":'2013002'} 4 }, 5 { 6 $project:{'course':1} 7 }, 8 { 9 $unwind:"$course" 10 } 11 ]).pretty() 12 13 //将一个数组数据拆分成一行一行的数据
目标数据

拆分后的数据

$lookup(连接查询)
联查询的操作,查询出每个学生所选的课程名称
1 db.student.aggregate([ 2 { 3 $match : {"stu_number":'2013002'} 4 }, 5 { 6 $project:{'course':1} 7 }, 8 { 9 $unwind:"$course" 10 }, 11 { 12 $lookup:{ 13 from:'course', 14 localField:'course',//本身集合的键 15 foreignField:'_id',//连表集合的键 16 as:'courses'//别名 17 } 18 } 19 ]).pretty()
结果

$project函数
字符串函数
| $concat | 字符串的连接 |
| $strcasecmp | 大小写敏感的比较,返回数字 |
| $substr | 获取字符串 |
| $toLower | 转换小写 |
| $toUpper | 转换大写 |
1 db.user.aggregate([ 2 { 3 $match : {"name":'tom'} 4 }, 5 { 6 $project:{'name':{$toUpper:"$name"}} 7 } 8 ]).pretty() 9 将tom全部转换为大写
算数运算函数
| $add | 加法 |
| $divide | 除法 |
| $mod | 求余 |
| $multiply | 乘积 |
| $subtract | 减法 |

1 db.user.aggregate([ 2 { 3 $match : {"name":'tom'} 4 }, 5 { 6 $project:{'id':{$add:["$id","$is_admin"]}} 7 } 8 ]).pretty() 9 //我们将文档的id和标志进行相加
日期函数
| $dayOfYear | 一年中的某一天1-365 |
| $dayOfMonth | 一个月中的某一天 |
| $dayOfWeek | 一周的某一天 |
| $year | 年 |
| $month | 月 |
| $week | 周 |
| $hour | 小时 |
| $minute | 分钟 |
| $second | 秒 |
| $millisecond | 毫秒 |
db.user.insert({
"name" : "bob",
"date" : ISODate("2013-05-01 19:12:32")
})
1 db.user.aggregate([ 2 { 3 $match : {"name":'bob'} 4 }, 5 { 6 $project: 7 { 8 year: { $year: "$date" }, 9 month: { $month: "$date" }, 10 day: { $dayOfMonth: "$date" }, 11 hour: { $hour: "$date" }, 12 minutes: { $minute: "$date" }, 13 seconds: { $second: "$date" }, 14 milliseconds: { $millisecond: "$date" }, 15 dayOfYear: { $dayOfYear: "$date" }, 16 dayOfWeek: { $dayOfWeek: "$date" }, 17 week: { $week: "$date" } 18 } 19 } 20 ]).pretty()

集合函数
| $setEquals | 两个集合是否相等 |
| $setIntersection | 返回两个集合公共的元素 |
| $setDifference | 返回两个集合不同的元素 |
| $setUnion | 合并集合 |
| $setIsSubset | 第二个集合是否为第一个集合的子集 |
| $anyElementTrue | 如果某个元素集合为TRUE,返回TRUE |
| $allElementsTrue | 如果所有元素都为TRUE,返回TRUE |
1 db.student.aggregate([ 2 { 3 $match : {"stu_name":'小明'} 4 }, 5 { 6 $project: 7 { 8 "course": { $setUnion: ['$course',['0001']]} 9 } 10 } 11 ]).pretty() 12 //将两个集合进行合并

注意:集合管道操作索引只能在$match和$sort这两个函数使用,其他不能使用索引
注意:集合管道操作索引只能在$match和$sort这两个函数使用,其他不能使用索引
注意:集合管道操作索引只能在$match和$sort这两个函数使用,其他不能使用索引

浙公网安备 33010602011771号