📜  MongoDB-聚合

📅  最后修改于: 2020-11-27 05:56:19             🧑  作者: Mango


聚合操作处理数据记录并返回计算结果。聚合操作将来自多个文档的值分组在一起,并且可以对分组的数据执行各种操作以返回单个结果。在SQL中,count(*)和group by等效于MongoDB聚合。

Aggregate()方法

对于MongoDB中的聚合,您应该使用aggregate()方法。

句法

Aggregate()方法的基本语法如下-

>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

在集合中,您具有以下数据-

{
   _id: ObjectId(7df78ad8902c)
   title: 'MongoDB Overview', 
   description: 'MongoDB is no sql database',
   by_user: 'tutorials point',
   url: 'http://www.tutorialspoint.com',
   tags: ['mongodb', 'database', 'NoSQL'],
   likes: 100
},
{
   _id: ObjectId(7df78ad8902d)
   title: 'NoSQL Overview', 
   description: 'No sql database is very fast',
   by_user: 'tutorials point',
   url: 'http://www.tutorialspoint.com',
   tags: ['mongodb', 'database', 'NoSQL'],
   likes: 10
},
{
   _id: ObjectId(7df78ad8902e)
   title: 'Neo4j Overview', 
   description: 'Neo4j is no sql database',
   by_user: 'Neo4j',
   url: 'http://www.neo4j.com',
   tags: ['neo4j', 'database', 'NoSQL'],
   likes: 750
},

现在从上面的集合中,如果您想显示一个列表,说明每个用户编写了多少教程,那么您将使用下面的aggregate()方法:

> db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
{ "_id" : "tutorials point", "num_tutorial" : 2 }
{ "_id" : "Neo4j", "num_tutorial" : 1 }
>

以上用例的Sql等效查询将通过my_group by by_user选择by_user,count(*)

在上面的示例中,我们已经按字段by_user对文档进行了分组,并且在每次出现时按用户将sum的先前值递增。以下是可用的聚合表达式的列表。

Expression Description Example
$sum Sums up the defined value from all documents in the collection. db.mycol.aggregate([{$group : {_id : “$by_user”, num_tutorial : {$sum : “$likes”}}}])
$avg Calculates the average of all given values from all documents in the collection. db.mycol.aggregate([{$group : {_id : “$by_user”, num_tutorial : {$avg : “$likes”}}}])
$min Gets the minimum of the corresponding values from all documents in the collection. db.mycol.aggregate([{$group : {_id : “$by_user”, num_tutorial : {$min : “$likes”}}}])
$max Gets the maximum of the corresponding values from all documents in the collection. db.mycol.aggregate([{$group : {_id : “$by_user”, num_tutorial : {$max : “$likes”}}}])
$push Inserts the value to an array in the resulting document. db.mycol.aggregate([{$group : {_id : “$by_user”, url : {$push: “$url”}}}])
$addToSet Inserts the value to an array in the resulting document but does not create duplicates. db.mycol.aggregate([{$group : {_id : “$by_user”, url : {$addToSet : “$url”}}}])
$first Gets the first document from the source documents according to the grouping. Typically this makes only sense together with some previously applied “$sort”-stage. db.mycol.aggregate([{$group : {_id : “$by_user”, first_url : {$first : “$url”}}}])
$last Gets the last document from the source documents according to the grouping. Typically this makes only sense together with some previously applied “$sort”-stage. db.mycol.aggregate([{$group : {_id : “$by_user”, last_url : {$last : “$url”}}}])

管道概念

在UNIX命令中,shell流水线意味着可以对某些输入执行操作,并将输出用作下一条命令的输入,依此类推。 MongoDB在聚合框架中也支持相同的概念。有一组可能的阶段,每个阶段都作为一组文档作为输入,并生成一组结果文档(或在管道末尾生成最终的JSON文档)。然后可以将其用于下一阶段,依此类推。

以下是聚合框架中的可能阶段-

  • $ project-用于从集合中选择一些特定字段。

  • $ match-这是一个过滤操作,因此可以减少作为下一阶段输入的文档数量。

  • $ group-这将执行如上所述的实际聚合。

  • $ sort-对文档进行排序。

  • $ skip-这样,可以在给定数量的文档中向前跳过文档列表。

  • $ limit-从当前位置开始,以给定的数量限制要查看的文档数量。

  • $ unwind-用于展开使用数组的文档。当使用数组时,数据是一种预连接的,并且此操作将被撤消以再次具有单独的文档。因此,在本阶段中,我们将增加下一阶段的文档数量。