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这两个函数使用,其他不能使用索引