zoukankan      html  css  js  c++  java
  • mongoDB学习 mongo的聚合框架、join

    聚合框架详情 请参考官方文档 

    https://docs.mongodb.com/manual/aggregation/

    MongoDB 聚合框架(Aggregation Framework)是一个计算框架,它可以:

    作用在一个或几个集合上;

      • 对集合中的数据进行的一系列运算;

      • 将这些数据转化为期望的形式;

    从效果而言,聚合框架相当于 SQL 查询中的:

      • GROUP BY
      • LEFT OUTER JOIN
      • AS等
    整个聚合运算过程称为管道(Pipeline),它是由多个步骤(Stage)组成的
    每个管道:
      • 接受一系列文档(原始数据);
      • 每个步骤对这些文档进行一系列运算;
      • 结果文档输出给下一个步骤;

    pipeline = [$stage1, $stage2, ...$stageN];
    db.<COLLECTION>.aggregate(
        pipeline,
        { options }
    );

    常见的stage步骤

    步骤 作用 SQL等价运算符
    $match 过滤 WHERE
    $project 投影 AS
    $sort 排序 ORDER BY
    $group 分组 GROUP BY
    $skip/$limit 结果限制 SKIP/LIMIT
    $lookup 左外连接 LEFT OUTER JOIN

     常见步骤中的运算符

    $match $project $group
    $eq/$gt/$gte/$lt/$lte
    $and/$or/$not/$in
    $geoWithin/$intersect
    ……
    选择需要的或排除不需要的字段
    $map/$reduce/$filter
    $range
    $multiply/$divide/$substract/$add
    $year/$month/$dayOfMonth/$hour/$minute/$second
    ……
    $sum/$avg
    $push/$addToSet
    $first/$last/$max/$min
    ……

      其他功能

    步骤 作用 SQL等价运算符
    $unwind 展开数组 N/A
    $graphLookup 图搜索 N/A
    $facet/$bucket 分面搜索 N/A

    比如展开数据就有妙用,可以将内嵌文档展开为多行数据。

    使用示例:

      条件过滤步骤 $match

      投影步骤 $project

      展开数据步骤 $unwind

      分组聚合步骤 $group 

     

    mongoSQl特有步骤$bucket

    $bucket 和select 中的case when 比较像。

    $Facet组合$bucket

     

     数据样例

    计算到目前为止的所有订单的总销售额
    db.orders.aggregate([
          { $group:
              {
                _id: null,
                total: { $sum: "$total" }
              }
          }
    ])
    // 结果: // { "_id" : null, "total" : NumberDecimal("44019609") }
    查询2019年第一季度(1月1日~3月31日)已完成订单(completed)的订单总金额和订单总数
    db.orders.aggregate([
    // 步骤1:匹配条件
          { $match: { status: "completed", orderDate: {
                  $gte: ISODate("2019-01-01"),
                  $lt: ISODate("2019-04-01") }
                 }
          },
    // 步骤二:聚合订单总金额、总运费、总数量       { $group: {             _id: null,             total: { $sum: "$total" },             shippingFee: { $sum: "$shippingFee" },             count: { $sum: 1 } }
          },       { $project: {       
    // 计算总金额 sum(a+b) as grandTotal         grandTotal: { $add: ["$total", "$shippingFee"] },         count: 1,         _id: 0 }
          } ])
    // 结果: // { "count" : 5875, "grandTotal" : NumberDecimal("2636376.00") }

     join操作

    适用场景:

    一般情况下,设计合理的mongoDB的文档嵌套模型可以避免频繁适用join操作,但是还是有些场景,需要设计主表和关联表做join

    1. 内嵌文档数据多,可能上万条或者更多。

    2.内嵌文档数据量大,可能数 MB 或者超过 16MB,而且并非常用字段。 
    3.内嵌文档或数组元素会频繁修改,一直增长。

    mongoDB join的适用限制

    MongoDB 对使用引用的集合之间并无主外键检查
    MongoDB 使用聚合框架的 $lookup 来模仿关联查询
    $lookup 只支持 left outer join
    $lookup 的关联目标(from)不能是分片表

    example1:

    db.contacts.aggregate([
      {
        $lookup:
          {
            from: "groups",
            localField: "group_ids",
            foreignField: "group_id",
            as: "groups"
          }
      }
    ])
    //select a.xx from contacts a left join groups b on a.group_ids=b.group_id
    //as 是起的别名

    example2:

    //表1
    db.orders.insert([
       { "_id" : 1, "item" : "almonds", "price" : 12, "quantity" : 2 },
       { "_id" : 2, "item" : "pecans", "price" : 20, "quantity" : 1 },
       { "_id" : 3  }
    ])
    //表2
    db.inventory.insert([
       { "_id" : 1, "sku" : "almonds", description: "product 1", "instock" : 120 },
       { "_id" : 2, "sku" : "bread", description: "product 2", "instock" : 80 },
       { "_id" : 3, "sku" : "cashews", description: "product 3", "instock" : 60 },
       { "_id" : 4, "sku" : "pecans", description: "product 4", "instock" : 70 },
       { "_id" : 5, "sku": null, description: "Incomplete" },
       { "_id" : 6 }
    ])
    //join示例
    db.orders.aggregate([
       {
         $lookup:
           {
             from: "inventory",
             localField: "item",
             foreignField: "sku",
             as: "inventory_docs"
           }
      }
    ])

    返回结果

       "_id" : 1,
       "item" : "almonds",
       "price" : 12,
       "quantity" : 2,
       "inventory_docs" : [
          { "_id" : 1, "sku" : "almonds", "description" : "product 1", "instock" : 120 }
       ]
    }
    {
       "_id" : 2,
       "item" : "pecans",
       "price" : 20,
       "quantity" : 1,
       "inventory_docs" : [
          { "_id" : 4, "sku" : "pecans", "description" : "product 4", "instock" : 70 }
       ]
    }
    {
       "_id" : 3,
       "inventory_docs" : [
          { "_id" : 5, "sku" : null, "description" : "Incomplete" },
          { "_id" : 6 }
       ]
    }

    上面是一对一的关联,还有多对多的关联,详情参考  官方文档:

    传送门 https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/

  • 相关阅读:
    VOA 2009/11/02 DEVELOPMENT REPORT In Kenya, a Better Life Through Mobile Money
    2009.11.26教育报道在美留学生数量创历史新高
    Java中如何实现Tree的数据结构算法
    The Python Tutorial
    VOA HEALTH REPORT Debate Over New Guidelines for Breast Cancer Screening
    VOA ECONOMICS REPORT Nearly Half of US Jobs Now Held by Women
    VOA ECONOMICS REPORT Junior Achievement Marks 90 Years of Business Education
    VOA 2009/11/07 IN THE NEWS A Second Term for Karzai; US Jobless Rate at 10.2%
    Ant入门
    Python 与系统管理
  • 原文地址:https://www.cnblogs.com/yanghaolie/p/13164367.html
Copyright © 2011-2022 走看看