MongoDB-聚合管道

MongoDB聚合管道

  • 使用聚合管道可以对集合中的文档进行变换和组合
    • db.COLLECTION_NAME.aggregate([{<stage>}, ...]) 方法构建和使用聚合管道
  • 可用作 表关联查询、数据的统计

管道操作符

  • $project 增加、删除、重命名字段
  • $match 条件匹配。只满足条件的文档才能进入下一阶段
  • $limit 限制结果的数量
  • $skip 跳过文档的数量
  • $sort 条件排序
  • $group 条件组合结果
  • $lookup 引入其他集合的数据(表关联查询)

SQL和NOSQL对比

where       $metch
group by    $group
having      $match
select      $project
order by    $sort
limit       $limit
sum()       $sum
count()     $sum
join        $lookup

管道表达式

  • 管道操作符为 “键” 所对应的 “值” 叫做管道表达式
    • 如:{$match: {status: "A"}}
      • $match 称为管道操作符
      • status: “A” 称为管道表达式,是管道操作符的操作数
  • 每个管道表达式是一个文档结构,由字段名、字段值和一些表达式操作符组成的

模拟数据

db.order.insert({
    
    "order_id":"1", "uid":10, "trade_no":"111", "all_price":100, "all_num":2})
db.order.insert({
    
    "order_id":"2", "uid":7, "trade_no":"222", "all_price":90, "all_num":2})
db.order.insert({
    
    "order_id":"3", "uid":9, "trade_no":"333", "all_price":20, "all_num":6})


db.order_item.insert({
    
    "order_id":"1", "title":"鼠标", "price":50, "num":1})
db.order_item.insert({
    
    "order_id":"1", "title":"键盘", "price":50, "num":1})


db.order_item.insert({
    
    "order_id":"2", "title":"牛奶", "price":50, "num":1})
db.order_item.insert({
    
    "order_id":"2", "title":"酸奶", "price":40, "num":1})

db.order_item.insert({
    
    "order_id":"3", "title":"矿泉水", "price":2, "num":5})
db.order_item.insert({
    
    "order_id":"3", "title":"毛巾", "price":10, "num":1})

管道操作符使用

$project 修改文档的结构,可用来重命名、增加或删除文档中的字段
  • 要求查找 order 表中只返回文档中的 trade_no 和 all_price 字段
    • db.order.aggregate([{$project:{trade_no:1, all_price: 1}}])
$match 用于过滤文档 类似于 find() 方法中的参数
  • db.order.aggregate(
        [
            {
          
          
                $project: {
          
          trade_no:1, all_price: 1}
            },
            {
          
          
                $match: {
          
          "all_price": {
          
          $gte: 90}}
            }
        
        ])
    
$group 将集合中的文档进行分组,可用于统计结果
  • 统计每个订单的订单数量,按照订单号分组

    db.order_item.aggregate(
    	[
            {
          
          
                $group: {
          
          _id: "$order_id", total: {
          
          $sum: "$num"}}
            }
        ]
    )
    
  • 统计每个订单的总价格,按照订单号分组

    db.order_item.aggregate(
    	[
            {
          
          
                $group: {
          
          _id: "$order_id", total: {
          
          $sum: "$price"}}
            }
        ]
    )
    
$sort 将集合中的文档进行排序
  • ​ 排序

    db.order.aggregate(
        [
            {
          
          
                $project: {
          
          trade_no:1, all_price: 1}
            },
            {
          
          
                $match: {
          
          "all_price": {
          
          $gte: 90}}
            },
            {
          
          
                $sort: {
          
          "all_price": -1}
            }
        ])
    
$limit
  • 限制查找数量

    db.order.aggregate(
        [
            {
          
          
                $project: {
          
          trade_no:1, all_price: 1}
            },
            {
          
          
                $match: {
          
          "all_price": {
          
          $gte: 90}}
            },
            {
          
          
                $sort: {
          
          "all_price": -1}
            },
            {
          
          
                $limit: 1
            }
        ])
    
$skip
  • 跳过查找
    db.order.aggregate(
        [
            {
          
          
                $project: {
          
          trade_no:1, all_price: 1}
            },
            {
          
          
                $match: {
          
          "all_price": {
          
          $gte: 90}}
            },
            {
          
          
                $sort: {
          
          "all_price": -1}
            },
            {
          
          
                $skip: 1
            }
        ])
    
$lookup
  • 表关联查询

    db.order.aggregate(
    	[
            {
          
          
                $lookup: {
          
          
                    from: "order_item",
                    //主表
                    localField: "order_id",
                    //附属表
                    foreignField: "order_id",
                    as: "items"
                }
            }
        ]
    )
    
    
  • 关联后找出价格大于等于90的数据

    db.order.aggregate(
    	[
            {
          
          
                $lookup: {
          
          
                    from: "order_item",
                    //主表
                    localField: "order_id",
                    //附属表
                    foreignField: "order_id",
                    as: "items"
                }
            },
            {
          
          
                $match: {
          
          
                    "all_price": {
          
          $gte: 90}
                }
            }
        ]
    )
    
  • 边关联后添加管道过滤 并 格式化输出

db.order.aggregate(
	[
        {
    
    
            $lookup: {
    
    
                from: "order_item",
                //主表
                localField: "order_id",
                //附属表
                foreignField: "order_id",
                as: "items"
            }
        },
        {
    
    
            $project: {
    
    
                order_id: 1,
                trade_no: 1,
                all_price: 1,
                items: 1
            }
        },
        {
    
    
            $match: {
    
    
                "all_price": {
    
    $gte: 90}
            }
        },
        {
    
    
            $sort: {
    
    
                "all_price": -1
            }
        }
    ]
).pretty()

猜你喜欢

转载自blog.csdn.net/it_xcr/article/details/112647191