MongoDB之聚合

1.  聚合管道

    MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。

    1.  聚合框架中常用的操作

        $project  <===>    sql的AS  表示要展示的字段

          1.  语法

              { $project: { <specification(s)> } }

          2.  实例            

db.sales.aggregate( [
  {
    $group: {
       _id: "$item",
       count: { $sum: {$multiply:["$price","$quantity"]} }
    }
    
  },

  {
    $project:{"_id":1}
  }
] )

结果只显示:_id这个字段

        $match         <===>    sql的select

          1.  语法

{ $match: { <query> } }

          2.  实例

db.student.insert([
{ "_id" : ObjectId("512bc95fe835e68f199c8686"), "author" : "dave", "score" : 80, "views" : 100 },
{ "_id" : ObjectId("512bc962e835e68f199c8687"), "author" : "dave", "score" : 85, "views" : 521 },
{ "_id" : ObjectId("55f5a192d4bede9ac365b257"), "author" : "ahn", "score" : 60, "views" : 1000 },
{ "_id" : ObjectId("55f5a192d4bede9ac365b258"), "author" : "li", "score" : 55, "views" : 5000 },
{ "_id" : ObjectId("55f5a1d3d4bede9ac365b259"), "author" : "annT", "score" : 60, "views" : 50 },
{ "_id" : ObjectId("55f5a1d3d4bede9ac365b25a"), "author" : "li", "score" : 94, "views" : 999 },
{ "_id" : ObjectId("55f5a1d3d4bede9ac365b25b"), "author" : "ty", "score" : 95, "views" : 1000 }
])

db.articles.aggregate(
    [ { $match : { author : "dave" } } ]
); 

        $limit   <===>  sql的limit

          1.  语法

              { $limit: <positive integer> }

          2.  实例

db.sales.aggregate( [
  {
    $group: {
       _id: "$item",
       count: { $sum: {$multiply:["$price","$quantity"]} }
    }
    
  },

  {
    $project:{"_id":1}
  },

  { $limit:1
  }
] )

        $skip  在聚合管道中跳过指定数量的文档,并返回余下的文档

        $unwind  将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值

        $group  <===>  sql的group by

          1.  语法

{
  $group:
    {
      _id: <expression>, // Group key
      <field1>: { <accumulator1> : <expression1> },
      ...
    }
 }  

          2.  实例

db.sales.insertMany([
  { "_id" : 1, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("2"), "date" : ISODate("2014-03-01T08:00:00Z") },
  { "_id" : 2, "item" : "jkl", "price" : NumberDecimal("20"), "quantity" : NumberInt("1"), "date" : ISODate("2014-03-01T09:00:00Z") },
  { "_id" : 3, "item" : "xyz", "price" : NumberDecimal("5"), "quantity" : NumberInt( "10"), "date" : ISODate("2014-03-15T09:00:00Z") },
  { "_id" : 4, "item" : "xyz", "price" : NumberDecimal("5"), "quantity" :  NumberInt("20") , "date" : ISODate("2014-04-04T11:21:39.736Z") },
  { "_id" : 5, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("10") , "date" : ISODate("2014-04-04T21:23:13.331Z") },
  { "_id" : 6, "item" : "def", "price" : NumberDecimal("7.5"), "quantity": NumberInt("5" ) , "date" : ISODate("2015-06-04T05:08:13Z") },
  { "_id" : 7, "item" : "def", "price" : NumberDecimal("7.5"), "quantity": NumberInt("10") , "date" : ISODate("2015-09-10T08:43:00Z") },
  { "_id" : 8, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("5" ) , "date" : ISODate("2016-02-06T20:20:13Z") },
])

db.sales.aggregate( [
  {
    $group: {
       _id: null,
       count: { $sum: 1 }
    }
  }
] )

类似于
SELECT COUNT(*) AS count FROM sales  

统计每个item的总数

db.sales.aggregate( [
{
$group: {
_id: "$item",
count: { $sum: 1 }
}
}
] )

   统计每个item的price的总和

db.sales.aggregate( [
{
$group: {
_id: "$item",
count: { $sum: "$price" }
}
}
] )

 统计每个item的price的平均值

db.sales.aggregate( [
{
$group: {
_id: "$item",
count: { $avg: "$price" }
}
}
] )

统计每个item的price*quantity的总和

db.sales.aggregate( [
{
$group: {
_id: "$item",
count: { $sum: {$multiply:["$price","$quantity"]} }
}
}
] )      

        $sort  <===>  sql的desc asc

        $lookup  <===>  sql的join

          1.  语法

{
   $lookup:
     {
       from: <collection to join>,
       localField: <field from the input documents>,
       foreignField: <field from the documents of the "from" collection>,
       as: <output array field>
     }
}

          2.  例子

db.orders.insert([
   { "_id" : 1, "item" : "almonds", "price" : 12, "quantity" : 2 },
   { "_id" : 2, "item" : "pecans", "price" : 20, "quantity" : 1 },
   { "_id" : 3  }
])

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

db.orders.aggregate([
   {
     $lookup:
       {
         from: "inventory",
         localField: "item",
         foreignField: "sku",
         as: "inventory_docs"
       }
  }
])

类似于sql的:
SELECT *, inventory_docs
FROM orders
WHERE inventory_docs IN (SELECT *
FROM inventory
WHERE sku= orders.item);      

        $out  将聚合管道的结果文档写入集合

    2.  $match和$lookup结合使用        

db.orders.aggregate([
   {
     $lookup:
       {
         from: "inventory",
         localField: "item",
         foreignField: "sku",
         as: "inventory_docs"
       }
   },
   {
      $match: {"price":{$gt:10}}
  },
])              

2.  Map-Reduce

3.  单用途聚合操作

 

posted @ 2022-09-16 13:29  奋斗史  阅读(30)  评论(0)    收藏  举报