MongoDB 语法语句【 高级查询 aggregate 聚合管道 】
使用聚合管道可以对集合中的文档进行变换与组合。
命令模板:
db.collectionName.aggregate( [ {<stage>,...} ] )
聚合的表达式:
表达式 | 描述 | 实例 |
---|---|---|
$sum | 计算总和。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}]) |
$avg | 计算平均值 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}]) |
$min | 获取集合中所有文档对应值得最小值。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}]) |
$max | 获取集合中所有文档对应值得最大值。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}]) |
$push | 在结果文档中插入值到一个数组中。 | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}]) |
$addToSet | 在结果文档中插入值到一个数组中,但不创建副本。 | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}]) |
$first | 根据资源文档的排序获取第一个文档数据。 | db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}]) |
$last | 根据资源文档的排序获取最后一个文档数据 | db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}]) |
管道操作符:
命令 | 功能描述 |
$project | 指定输出文档里的字段. |
$match | 选择要处理的文档,与fine()类似。 |
$limit | 限制传递给下一步的文档数量。 |
$skip | 跳过一定数量的文档。 |
$unwind | 扩展数组,为每个数组入口生成一个输出文档。 |
$group | 根据key来分组文档。 |
$sort | 排序文档。 |
$geoNear | 选择某个地理位置附近的的文档。 |
$out | 把管道的结果写入某个集合。 |
$redact | 控制特定数据的访问。 |
$lookup |
多表关联(3.2版本新增) |
先录入模拟数据以方便演示:
db.order.insertMany( [ {order_id:"1",uid:"10",trade_no:"111",all_price:1550,all_num:5}, {order_id:"2",uid:"7",trade_no:"222",all_price:140,all_num:4}, {order_id:"3",uid:"9",trade_no:"333",all_price:15000,all_num:2}, ] )
db.order_item.insertMany( [ {order_id:"1",title:"茶轴键盘",price:50,num:1}, {order_id:"1",title:"双飞燕鼠标",price:20,num:1}, {order_id:"1",title:"Sony音响",price:200,num:1}, {order_id:"1",title:"aoc显示器",price:780,num:1}, {order_id:"1",title:"华硕主板",price:500,num:1}, ] )
db.order_item.insertMany( [ {order_id:"2",title:"养乐多",price:20,num:2}, {order_id:"2",title:"金典牛奶",price:10,num:4}, {order_id:"2",title:"优乐美",price:5,num:6}, {order_id:"2",title:"伊利牛奶",price:15,num:2}, ] )
db.order_item.insertMany( [ {order_id:"3",title:"小米10",price:5000,num:1}, {order_id:"3",title:"华为Mate40",price:10000,num:1}, ] )
1、$project 实例:
默认情况下, _id 是包含的,如果不想要,可以设置 _id:0
db.order.aggregate( [ {$project:{_id:0,trade_no:1,all_num:1}} ] )
2、$match 实例:筛选符合条件的数据显示出来
db.order.aggregate( [ {$project:{_id:0,trade_no:1,all_num:1}}, {$match:{all_num:{$gte:4}}} ] )
3,、$limit : 一页显示几条;
$skip : 跳过多少条;
$sort : 用于排序。
这三个和常规的用法类似。
db.order.aggregate( [ {$project:{trade_no:1,all_num:1}} {$limit:2}, {$skip:1} ] ) db.order.aggregate( [ {$project:{_id:0,trade_no:1,all_num:1}}, {$sort:{all_num:-1}} ] )
4、$lookup : 关联表 ,重要的一个。
主要功能 是将每个输入待处理的文档,经过$lookup 阶段的处理,输出的新文档中会包含一个新生成的数组列(户名可根据需要命名新key的名字 )。数组列存放的数据 是 来自 被Join 集合的适配文档,如果没有,集合为空(即 为[ ])
语法值 | 解释说明 |
from
|
同一个数据库下等待被Join的集合。 |
localField
|
源集合中的match值,如果输入的集合中,某文档没有 localField 这个Key(Field),在处理的过程中,会默认为此文档含 有 localField:null的键值对。 |
foreignField
|
待Join的集合的match值,如果待Join的集合中,文档没有foreignField 值,在处理的过程中,会默认为此文档含有 foreignField:null的键值对。 |
as
|
为输出文档的新增值命名。如果输入的集合中已存在该值,则会覆盖掉, |
语法例子:
db.order.aggregate( [ {$lookup:{ from:"order_item", localField:"order_id", foreignField:"order_id", as:"items" }}, {$project:{_id:0}}, {$match:{all_price:{$gte:1000}}}, {$sort:{all_num:1}}, ] )