• MongoDb/Mongoose 中使用 aggregate 聚合管道


    一、MongoDB 聚合管道(Aggregation Pipeline)

    使用聚合管道可以对集合中的文档进行变换和组合。 实际项目:表关联查询、数据的统计。

    MongoDB 中使用 db.COLLECTION_NAME.aggregate([{<stage>},...]) 方法 来构建和使用聚合管道。先看下官网给的实例,聚合管道的用法:

    二、MongoDB Aggregation 管道操作符与表达式

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

    SQL NOSQL 对比:

    管道表达式: 管道操作符作为”,所对应的叫做管道表达式。

    例如{$match:{status:"A"}}$match 称为管道操作符,而 status:"A"称为管道表达式, 是管道操作符的操作数(Operand)

    每个管道表达式是一个文档结构,它是由字段名、字段值、和一些表达式操作符组成的。


    三、 数据模拟

    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":"商品鼠标 1","price":50,num:1})
    db.order_item.insert({"order_id":"1","title":"商品键盘 2","price":50,num:1})
    db.order_item.insert({"order_id":"1","title":"商品键盘 3","price":0,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"}}
    } 
    ])

    七、 $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

    使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。注:skip()方法默认参数为 0 。

    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"
    } }
    ])

    十一、 Mongoose aggregate 多表关联查询

    /*
    db.order.aggregate([
        {
          $lookup:
            {
              from: "order_item",
              localField: "order_id",
              foreignField: "order_id",
              as: "items"
            }
       },
    {
        $match:{"all_price":{$gte:90}}
    }
    
    ])
    
    */
    
    
    
    
    
    
    
    var OrderModel=require('./model/order.js');
    
    
    //查询order 表的数据
    
    /*
        OrderModel.find({},function(err,docs){
    
            console.log(docs);
    
        })
    */
    
    
    
    //order表关联order_item
    OrderModel.aggregate([
    
        {
            $lookup:
              {
                from: "order_item",
                localField: "order_id",
                foreignField: "order_id",
                as: "items"
              }
         },
         {
            $match:{"all_price":{$gte:90}}
         }
    
    ],function(err,docs){
    
        if(err){
    
            console.log(err);
            return;
        }
    
        console.log(JSON.stringify(docs))
    })

    order.js

    var mongoose=require('./db.js');
    
    
    var OrderSchema=mongoose.Schema({
    
        order_id:String,
        uid:Number,
        trade_no:String,
        all_price:Number,
        all_num:Number    
    })
    
    module.exports=mongoose.model('Order',OrderSchema,'order');
  • 相关阅读:
    NET开源框架(转载)
    数据行转列的应用(json数据源)
    防止通过URL下载文件
    jquery中的$.post()方法无法给变全局变量的问题
    页面乱码问题的解决方案
    在mvc中使用Ninject进行依赖注入
    在mvc4.0中使用json数据
    使用thinkphp3.2中的验证码功能
    ThinkPHP中邮件发送功能
    ASP.NET页面运行机制
  • 原文地址:https://www.cnblogs.com/loaderman/p/11516474.html
Copyright © 2020-2023  润新知