MongoDB 聚合函数(第 14 天)

作者 : 慕源网 本文共10998个字,预计阅读时间需要28分钟 发布时间: 2021-11-2 共330人阅读

在阅读本文之前,我强烈建议您阅读本系列的前几期:

介绍

聚合函数对文档组执行操作并返回计算结果。聚合的工作主要是对多个文档的数据进行分组,并对分组后的数据进行各种操作,并返回单个或多个结果。

聚合函数的类型

MongoDB 以以下三种方式之一执行聚合操作。

  • 单一用途的聚合方法和命令。
  • Pipeline
  • Map Reduce

首先,我们将创建一个“Demo”集合并将以下数据插入到该集合中。

{  
    "_id": ObjectId("55dc6c94b32228b6ef8753c0"),  
    "Name": "Pankaj Choudhary",  
    "Age": 21,  
    "Salary": 25000  
}   
{  
    "_id": ObjectId("55dc6ca8b32228b6ef8753c1"),  
    "Name": "Sandeep Jangid",  
    "Age": 22,  
    "Salary": 27000  
}   
{  
    "_id": ObjectId("55dc6cb9b32228b6ef8753c2"),  
    "Name": "Rahul Prajapat",  
    "Age": 23,  
    "Salary": 37000  
}   
{  
    "_id": ObjectId("55dc6ccab32228b6ef8753c3"),  
    "Name": "Sanjeev Baldia",  
    "Age": 22,  
    "Salary": 28000  
}   
{  
    "_id": ObjectId("55dc6cdcb32228b6ef8753c4"),  
    "Name": "Narendra Sharma",  
    "Age": 25,  
    "Salary": 25000  
}   
{  
    "_id": ObjectId("55dc6cf5b32228b6ef8753c5"),  
    "Name": "Nitin Yadav",  
    "Age": 28,  
    "Salary": 35000  
}   
{  
    "_id": ObjectId("55dc6d09b32228b6ef8753c6"),  
    "Name": "Omveer Choudhary",  
    "Age": 32,  
    "Salary": 37000  
}

首先,我们将阅读有关单一用途的聚合。

单一用途的聚合方法和命令

顾名思义,单一用途的聚合方法用于对数据集进行特定的聚合操作。与管道和映射归约操作相比,单一用途的聚合方法不那么复杂,但范围有限。单一用途的聚合方法和命令为常见的数据处理选项提供了直接的语义。

以下是一些重要的单一用途操作。

Count

Count 操作需要一些文档,并根据匹配查询返回文档的计数。在 MongoDB 中,count 命令和 cursor.count() 方法用于进行计数操作。

示例 1

 

db.Demo.count()

输出

7

在此示例中,Demo.count() 是一个游标方法,它返回 Demo 集合中存在的所有文档的计数。

示例 2

 

db.runCommand({count: 'Demo' ,query:{Salary:{$gt:30000}}})  

输出

{ “n” : 3, “ok” : 1 }

在本例中,count 命令获取所有 Salary 字段值大于 30000 的文档并返回计数。

Distinct

Distinct 操作获取一个文档,并根据匹配查询返回字段的唯一值。在 MongoDB 中, cursor.distinct() 方法和 distinct 命令执行不同的操作。

示例 1

 

db.Demo.distinct("Salary")

输出

[ 25000, 27000, 37000, 28000, 35000 ]

在本例中,我们使用不同的游标方法返回“Salary”字段的不同值。

示例 2

 

db.runCommand({distinct: 'Demo' ,key: "Salary" ,query:{Salary:{$gt:30000}}})

输出

 

{  
    "values":   
    [  
        37000,  
        35000  
    ],  
    "stats":   
    {  
        "n": 3,  
        "nscanned": 0,  
        "nscannedObjects": 7,  
        "timems": 598,  
        "planSummary": "COLLSCAN"  
    },  
    "ok": 1  
}

在此示例中,distinct 命令返回“Salary”字段的值大于 30000 的“Salary”字段的不同值。

Group

Group 操作采用多个文档,并根据匹配查询创建一组字段按它们的值分组,最后返回一个文档数组,其中包含每个组的计算结果。在 MongoDB 中, group 命令和 cursor.group() 方法执行组操作。

示例 1 

 

db.Demo.group({key:{Age:1},reduce:function(cur,result){result.Salary+=cur.Salary},initial:{Salary:0}})  

输出

 

[  
  {  
    "Age": 21,  
    "Salary": 25000  
},  
  {  
    "Age": 22,  
    "Salary": 55000  
},  
  {  
    "Age": 23,  
    "Salary": 37000  
},  
  {  
    "Age": 25,  
    "Salary": 25000  
},  
  {  
    "Age": 28,  
    "Salary": 35000  
},  
  {  
    "Age": 32,  
    "Salary": 37000  
}]

在这个例子中,我们使用了组游标方法。此方法根据“Age”字段的值对文档进行分组,并计算每个组的工资总和。

示例 2

 

db.runCommand({group:{ns:'Demo',key:{Salary:1},cond:{Salary:{$lt:30000}},$reduce:function(cur,resu  
lt){result.Age+=cur.Age},initial:{Age:10}}})  

输出

 

{  
    "retval":   
    [  
      {  
        "Salary": 25000,  
        "Age": 56  
    }, {  
        "Salary": 27000,  
        "Age": 32  
    }, {  
        "Salary": 28000,  
        "Age": 32  
       }  
    ],  
    "count": NumberLong(4),  
    "keys": NumberLong(3),  
    "ok": 1  
}

在本例中,我们使用 group 命令。此命令根据 Salary 字段的值对文档进行分组,并计算每个组的 Age 字段的总和。

聚合管道

管道意味着可以对某些输入执行操作并将输出用作下一个命令的输入等等。聚合管道是一个以数据处理管道概念为模型的框架。在聚合管道中,文档进入多级管道,将文档转换为聚合结果。管道操作使用匹配查询来获取准确的文档并分组以生成文档组。管道操作提供了按指定字段对文档进行排序的工具。管道操作包含许多阶段,例如像查询一样操作的过滤器和修改输出形式的文档转换。主要是聚合命令对单个集合进行操作,并将整个集合传递到聚合管道中。

聚合管道是 map-reduce 的替代方案。它可能是聚合操作的合适选择,因为 map-reduce 不必要地复杂。但是管道在值类型和结果大小方面有一些有限的行为。

语法

db.Collection_Name.aggregate({Pipeline expression})

参数

管道表达式:管道表达式指定要应用于输入文档的转换。管道表达式仅对管道阶段的当前文档进行操作。

在聚合管道中,文档经过多个阶段,每个阶段将文档转换为另一种形式。不建议每个流水线阶段都针对每个文档生成一个文档。某些阶段可能会减少某些文档并可能生成新文档。

管道聚合包含多个阶段,每个阶段将一些文档作为输入,并对这些文档进行操作并生成输出。以下是聚合管道中可能的阶段:

阶段

描述

$project 从集合中选择特定字段
$match 指定选择标准,以减少文档数量
$group 用于将文档分成不同的组
$sort 对文档进行排序
$skip 用于跳过多个文档
$limit 定义输出结果中的文档数
$unwind 使用数组展开文档
$redact 通过限制每个文档的内容来重塑每个文档
$出 它是管道的最后阶段,将聚合管道的结果文档写入集合。

让我们看一个例子来理解聚合管道的概念。

示例 1

db.Demo.aggregate([{$group:{_id:"$Age",Salary_Is:{$sum:"$Salary"}}}])

输出

{  
    "_id": 32,  
    "Salary_Is": 37000  
}   
{  
    "_id": 25,  
    "Salary_Is": 25000  
}   
{  
    "_id": 23,  
    "Salary_Is": 37000  
}   
{  
    "_id": 22,  
    "Salary_Is": 55000  
}   
{  
    "_id": 28,  
    "Salary_Is": 35000  
}   
{  
    "_id": 21,  
    "Salary_Is": 25000  
}

在这个例子中,我们按字段“Age”对文档进行分组,并且对于每个组,我们计算 Salary 的总和。以下是此示例的等效 SQL 查询。

从 Demo 组中按 Age 选择 Age, sum(Salary)。

示例 2
db.Demo.aggregate
([{  
    $group: {  
        _id: "$Age",  
        Sum_Salary: {  
            $sum: "$Salary"  
        },  
        Avg_Salary: {  
            $avg: "$Salary"  
        },  
        Min  
        _Salary: {  
            $min: "$Salary"  
        },  
        Max_Salary: {  
            $max: "$Salary"  
        }  
    }  
}])

输出

{    
    "_id": 32,    
    "Sum_Salary": 37000,    
    "Avg_Salary": 37000,    
    "Min_Salary": 37000,    
    "Max_Salary": 37000    
}     
{    
    "_id": 25,    
    "Sum_Salary": 25000,    
    "Avg_Salary": 25000,    
    "Min_Salary": 25000,    
    "Max_Salary": 25000    
}     
{    
    "_id": 23,    
    "Sum_Salary": 37000,    
    "Avg_Salary": 37000,    
    "Min_Salary": 37000,    
    "Max_Salary": 37000    
}     
{    
    "_id": 22,    
    "Sum_Salary": 55000,    
    "Avg_Salary": 27500,    
    "Min_Salary": 27000,    
    "Max_Salary": 28000    
}     
{    
    "_id": 28,    
    "Sum_Salary": 35000,    
    "Avg_Salary": 35000,    
    "Min_Salary": 35000,    
    "Max_Salary": 35000    
}     
{    
    "_id": 21,    
    "Sum_Salary": 25000,    
    "Avg_Salary": 25000,    
    "Min_Salary": 25000,    
    "Max_Salary": 25000    
}  

在这个例子中,我们按“Age”字段对文档进行分组,并计算总和、平均、最低和最高工资。以下是 SQL 中的等效查询。

按年龄从 Demo 组中选择 Age, sum(Salary), avg(Salary), max(Salary), min(Salary)。

Select Age, sum(Salary), avg(Salary), max(Salary), min(Salary) from Demo group by Age.

示例 3

db.Demo.aggregate  
([{  
    $group:   
  {  
        _id: "$Age",  
        Sum_Salary:   
        {  
            $sum: "$Salary"  
        },  
        Avg_Salary:   
        {  
            $avg: "$Salary"  
        },  
        Min  
        _Salary:   
        {  
            $min: "$Salary"  
        },  
        Max_Salary:   
        {  
            $max: "$Salary"  
        }  
    }  
},   
   {  
    $match:   
    {  
        _id:   
         {  
            $gt: 21,  
            $lt: 27  
         }  
    }  
}])

输出

{  
    "_id": 25,  
    "Sum_Salary": 25000,  
    "Avg_Salary": 25000,  
    "Min_Salary": 25000,  
    "Max_Salary": 25000  
}   
{  
    "_id": 23,  
    "Sum_Salary": 37000,  
    "Avg_Salary": 37000,  
    "Min_Salary": 37000,  
    "Max_Salary": 37000  
}   
{  
    "_id": 22,  
    "Sum_Salary": 55000,  
    "Avg_Salary": 27500,  
    "Min_Salary": 27000,  
    "Max_Salary": 28000  
}

在这个例子中,文档通过两个阶段。第一阶段是“group”。在那个阶段,我们按“Age”字段对文档进行分组,并计算总和、平均、最低和最高工资。第二阶段是“match”,该阶段根据 Age 字段的值过滤所有文档。

以下查询也生成相同的输出

db.Demo.aggregate
([{  
    $match:   
    {  
        Age:   
        {  
            $gt: 21,  
            $lt: 27  
        }  
    }  
}, {  
    $group:   
    {  
        _id: "$Age",  
        Sum_Salary:   
        {  
            $sum: "$Salary"  
        },  
        Avg_Salary:   
        {  
            $avg: "$Salary"  
        },  
        Min_Salary:   
        {  
            $min: "$Salary"  
        },  
        Max_Salary:   
        {  
            $max: "$Salary"  
        }  
    }  
}]) 

以下是 SQL 中的等效查询。

Select Age, sum(Salary), avg(Salary), max(Salary), min(Salary) from Demo Where Age>21 And Age<27 group by Age

示例 4

db.Demo.aggregate
([{  
      $limit: 3  
  }, 
  {  
      $group:   
      {  
          _id: "$Age",  
              Sum_Salary:   
              {  
                  $sum: "$Salary"  
              },  
              Avg_Salary:   
              {  
                  $avg: "  
                  $Salary "  
              },  
              Min_Salary:{$min:"  
              $Salary "},Max_Salary:{$max:"  
              $Salary "}
        }  
  }])

输出

{  
    "_id": 23,  
    "Sum_Salary": 37000,  
    "Avg_Salary": 37000,  
    "Min_Salary": 37000,  
    "Max_Salary": 37000  
}   
{  
    "_id": 22,  
    "Sum_Salary": 27000,  
    "Avg_Salary": 27000,  
    "Min_Salary": 27000,  
    "Max_Salary": 27000  
}   
{  
    "_id": 21,  
    "Sum_Salary": 25000,  
    "Avg_Salary": 25000,  
    "Min_Salary": 25000,  
    "Max_Salary": 25000  
}

在这个例子中,文档通过两个阶段。第一阶段是“limit”,从集合中选择前 3 个文档并将这些文档传递给第二阶段。第二阶段按“Age”字段对文档进行分组,并计算总和、平均、最低和最高工资。

要点

聚合管道中阶段的顺序非常重要。像 db.Demo.aggregate($limit,$group) 和 db.Demo.aggregate($group,$limit) 一样,这些方法不提供相同的结果。

现在我们交换“limit”和“group”阶段的顺序执行前面的方法。

db.Demo.aggregate
([{  
    $group: 
{  
        _id: "$Age",  
        Sum_Salary: 
        {  
            $sum: "$Salary"  
        },  
        Avg_Salary: 
        {  
            $avg: "$Salary"  
        },  
        M  
        in_Salary: 
        {  
            $min: "$Salary"  
        },  
        Max_Salary: 
        {  
            $max: "$Salary"  
        }  
    }  
}, {  
    $limit: 3  
}])

输出

{  
    "_id": 32,  
    "Sum_Salary": 37000,  
    "Avg_Salary": 37000,  
    "Min_Salary": 37000,  
    "Max_Salary": 37000  
}   
{  
    "_id": 25,  
    "Sum_Salary": 25000,  
    "Avg_Salary": 25000,  
    "Min_Salary": 25000,  
    "Max_Salary": 25000  
}   
{  
    "_id": 23,  
    "Sum_Salary": 37000,  
    "Avg_Salary": 37000,  
    "Min_Salary": 37000,  
    "Max_Salary": 37000  
}

我们可以看到这个方法的结果和之前的方法是不一样的,所以阶段顺序的选择很重要。这个选择可能会改变预期的结果。

例 5

db.Demo.aggregate
([{  
    $group: 
    {  
        _id: "$Age",  
        Sum_Salary: {  
            $sum: "$Salary"  
        },  
        Avg_Salary: {  
            $avg: "$Salary"  
        },  
        M  
        in_Salary: {  
            $min: "$Salary"  
        },  
        Max_Salary: {  
            $max: "$Salary"  
        }  
    }  
}, {  
    $project: {  
        Sum_Salary: 1,  
        Max_Salary: 1,  
        _id: 0  
    }  
}, {  
    $limit: 4  
}])

输出

{  
    "Sum_Salary": 37000,  
    "Max_Salary": 37000  
}   
{  
    "Sum_Salary": 25000,  
    "Max_Salary": 25000  
}   
{  
    "Sum_Salary": 37000,  
    "Max_Salary": 37000  
}   
{  
    "Sum_Salary": 55000,  
    "Max_Salary": 28000  
}

在本示例中,文档经历了以下三个阶段。第一阶段是前面示例中所述的“group”。第二阶段是“project”。在那个阶段,我们只选择要显示的 Sum_Salary 和 Max_Salary 字段。第三个阶段是“限制”,在这个阶段我们从前一个阶段(项目)的结果中选择前4个文件。

例 6

db.Demo.aggregate([{  
    $group: {  
        _id: "$Age",  
        Sum_Salary: {  
            $sum: "$Salary"  
        },  
        Avg_Salary: {  
            $avg: "$Salary"  
        },  
        M  
        in_Salary: {  
            $min: "$Salary"  
        },  
        Max_Salary: {  
            $max: "$Salary"  
        }  
    }  
}, {  
    $project: {  
        Sum_Salary: 1,  
        Max_Salary: 1,  
        _id: 0  
    }  
}, {  
    $limit: 4  
}, {  
    $skip: 2  
}]) 

输出

{  
    "Sum_Salary": 37000,  
    "Max_Salary": 37000  
}   
{  
    "Sum_Salary": 55000,  
    "Max_Salary": 28000  
}

这个例子与前面的例子相同,但我们添加了一个额外的阶段,“skip”。所以“limit”阶段的结果被传递到“skip”阶段,这个阶段从集合中删除前2个文档并打印剩余的文档。

例 7

db.Demo.aggregate([{  
    $group: {  
        _id: "$Age",  
        Sum_Salary: {  
            $sum: "$Salary"  
        },  
        Avg_Salary: {  
            $avg: "$Salary"  
        },  
        M  
        in_Salary: {  
            $min: "$Salary"  
        },  
        Max_Salary: {  
            $max: "$Salary"  
        }  
    }  
}, {  
    $project: {  
        Sum_Salary: 1,  
        Max_Salary: 1,  
        _id: 0  
    }  
}, {  
    $limit: 4  
}, {  
    $sort: {  
        Sum_Salary: 1  
    }  
}])

输出

{  
    "Sum_Salary": 25000,  
    "Max_Salary": 25000  
}   
{  
    "Sum_Salary": 37000,  
    "Max_Salary": 37000  
}  
{  
    "Sum_Salary": 37000,  
    "Max_Salary": 37000  
}  
{  
    "Sum_Salary": 55000,  
    "Max_Salary": 28000  
}

此示例与示例 6 类似,但在此示例中,我们使用了一个额外的阶段“sort”。该阶段从“limit”阶段的输出中检索文档,并根据其中的 Sum_Salary 字段的值对文档进行排序升序。

示例 8

db.Demo.aggregate([{  
    $group: {  
        _id: "$Age",  
        Sum_Salary: {  
            $sum: "$Salary"  
        },  
        Avg_Salary: {  
            $avg: "$Salary"  
        },  
        M  
        in_Salary: {  
            $min: "$Salary"  
        },  
        Max_Salary: {  
            $max: "$Salary"  
        }  
    }  
}, {  
    $project: {  
        Sum_Salary: 1,  
        Max_Salary: 1,  
        _id: 0  
    }  
}, {  
    $redact: {  
        $cond: {  
            if: {  
                $gt: ["$Sum_Salary", 30000]  
            },  
            then: "$$PRUNE",  
            else: "$$DESCEND"  
        }  
    }  
}])

输出

{  
    "Sum_Salary": 25000,  
    "Max_Salary": 25000  
}   
{  
    "Sum_Salary": 25000,  
    "Max_Salary": 25000  
}

在这个例子中,我们使用了一个 redact 阶段。此阶段根据存储在文档本身中的信息限制文档的内容。在前面的 $redact 阶段,我们使用了两个系统变量。第一个变量是“ $$PRUNE ”,该变量排除当前文档中存在的所有字段或嵌入在文档级别的所有字段。第二个变量是“ $$DESCEND ”,它返回当前文档级别的所有字段,不包括嵌入级别的文档。所以前面的查询排除了“Sum_Salary”的值大于 30000 的所有文档。

Map-Reduce

Map-Reduce 是另一种进行聚合的方法。Map-Reduce 是两种操作的组合。Map-Reduce 的第一部分是“Map”,它处理每个文档并为每个输入文档检索一个或多个对象。Map-Reduce 的第二部分是“Reduce”,它结合了 Map 操作的结果。Map-Reduce 将大量数据处理成聚合结果。

Map-Reduce 操作的工作原理

 

对于 Map-Reduce 操作,MongoDB 提供了 mapReduce 数据库命令。在 Map-Reduce 操作中,MongoDB 首先对所有匹配查询条件的文档应用 map 操作。映射操作的结果生成键值对。对于那些具有多个值的键,MongoDB 应用减少操作来收集和压缩聚合结果。然后 MongoDB 将结果存储在一个集合中。Map-Reduce 还包含一个可选函数,finalize。我们可以将reduce操作的输出传递给finalize函数,进一步压缩聚合操作的结果。

MongoDB 在 map-reduce 聚合中使用 JavaScript 函数。Map-Reduce 聚合可以将文档作为输出返回,也可以将结果写入集合。Map-Reduce 使用提供高度灵活性的 JavaScript 函数。

让我们看一些 Map-Reduce 聚合的例子。

示例 1

要对任何集合执行 mapReduce 函数,我们必须执行以下三个步骤。现在我们将使用“Demo”集合来理解这些过程。

第1步

定义map函数。

function()
{  
   emit(this.Age,this.Salary);  
} ;  

在函数“this”中定义了当前集合名称。此函数将每个文档的 Salary 映射到 Age 并发出 Age 和 Salary 对。

第2步

定义reduce函数。

function(key,values)
{  
   return Array.sum(values);  
} 

使用两个参数键和值定义 reduce 函数。values 参数是一个数组类型,由 map 函数发出,包含薪水值并按年龄分组。此函数将 values 数组减少为其元素的总和。

第 3 步

输出集合。

{ out:"My_Coll"}

此操作将结果存储在“My_Coll”集合中。如果集合已经存在,则集合的内容将替换 mapReduce 函数的内容。

这三个步骤的组合形式是:

db.Demo.mapReduce(function() 
{  
    emit(this.Age, this.Salary);  
}, 
function(key, values) 
{  
    return Array.sum(v alues);  
}, 
{  
    query: 
    {  
        Age:   
        {  
            $gt: 20  
        }  
    },  
    out: "My_Coll"  
})

因此,当我们执行前面的查询时,MongoDB 会返回以下输出作为确认。

{  
   "result" : "My_Coll",  
   "timeMillis" : 4,  
   "counts" :    
   {  
      "input" : 7,  
      "emit" : 7,  
      "reduce" : 1,  
      "output" : 6  
   },  
      "ok" : 1  
}

前面的结果定义了输入文档的数量、发送文档的数量、减少文档的数量、输出的数量和执行 mapReduce 命令的时间。

前面查询的结果将存储在“My_Coll”集合中,因此我们可以使用 find() 方法从“My_Coll”集合中检索结果。

db.My_Coll.find().pretty()

输出

{  
    "_id": 21,  
    "value": 25000  
}   
{  
    "_id": 22,  
    "value": 55000  
}   
{  
    "_id": 23,  
    "value": 37000  
}   
{  
    "_id": 25,  
    "value": 25000  
}   
{  
    "_id": 28,  
    "value": 35000  
}   
{  
    "_id": 32,  
    "value": 37000  
}

示例 2

步骤 1

var map_func = function()    
{    
    emit(this.Age, this.Salary);    
}; 

第2步

var reduce_func = function(key, values)     
{    
    return Array.sum(values);    
};  

第 3 步

db.Demo.mapReduce(map_func, reduce_func,    
{    
    query:     
    {    
        Age:     
        {    
            $gt: 23    
        }    
    },    
    out: "My_Coll"    
})  

输出

{  
    "result": "My_Coll",  
    "timeMillis": 4,  
    "counts":   
    {  
        "input": 3,  
        "emit": 3,  
        "reduce": 0,  
        "output": 3  
    },  
    "ok": 1  
}

以下是My_Col集合的数据:

db.My_Coll.find().pretty()

输出

{  
    "_id": 25,  
    "value": 25000  
}   
{  
    "_id": 28,  
    "value": 35000  
}  
{  
    "_id": 32,  
    "value": 37000  
}

在这个例子中,我们将在两个变量中定义 map 和 reduce 函数,并在 mapReduce 函数中使用这两个变量。我们还定义了对定义选择标准的集合的查询。

例子 

db.Demo.mapReduce(  
function()   
{  
    emit(this.Age, this.Salary);  
},  
function(key, values)  
{  
    return Array.avg(v alues);  
}, {  
    query:   
    {  
        Age:   
        {  
            $gt: 20  
        },  
        Salary:   
        {  
            $gte: 24000  
        }  
    },  
    out: "My_Coll",  
    limit: 4,  
    sort:   
    {  
        Salary: 1  
    }  
})

输出

{  
    "result": "My_Coll",  
    "timeMillis": 5,  
    "counts": 
{  
        "input": 4,  
        "emit": 4,  
        "reduce": 1,  
        "output": 3  
},  
    "ok": 1  
}  
}

以下是My_Col集合的数据:

db.My_Coll.find().pretty()  

输出

{  
    "_id": 21,  
    "value": 25000  
}   
{  
    "_id": 22,  
    "value": 27500  
}   
{  
    "_id": 25,  
    "value": 25000  
}

今天,我们阅读了MongoDB中的聚合操作。聚合是 MongoDB 的一个重要部分,它计算记录并过滤结果。

感谢您阅读这篇文章!

下一篇 >> MongoDB 复制(第 15 天)


慕源网 » MongoDB 聚合函数(第 14 天)

常见问题FAQ

程序仅供学习研究,请勿用于非法用途,不得违反国家法律,否则后果自负,一切法律责任与本站无关。
请仔细阅读以上条款再购买,拍下即代表同意条款并遵守约定,谢谢大家支持理解!

发表评论

开通VIP 享更多特权,建议使用QQ登录