首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Pipline Mongodb聚合顺序

Pipline Mongodb聚合顺序
EN

Stack Overflow用户
提问于 2020-04-22 16:59:25
回答 1查看 29关注 0票数 0

我不小心尝试在publis集合上执行两个聚合命令:

代码语言:javascript
复制
db.publis.aggregate([  
    { $group : { _id : "$publisher" , count:{$sum:1} }  }   , 
    {$project: { _id:0 , count:1}  }  
])

db.publis.aggregate([ 
    {$project: { _id:0 , count:1}  }   , 
    { $group : { _id : "$publisher" , count:{$sum:1} }  }   ])

你能告诉我这个聚合函数是如何工作的吗?

EN

回答 1

Stack Overflow用户

发布于 2020-04-22 17:38:35

聚合将从输入集合中读取文档,然后沿着管道依次传递文档。stages可以从流中删除文档、创建新文档或修改现有文档。

项目

$project阶段选择要包括在文档中或从文档中排除的字段,并且可以使用运算符生成新值。

在您的示例中,_id:0告诉它在传递文档之前删除_id字段,count:1告诉它包含count字段。

因为您已经显式包含了一个字段,所以所有未提及的字段都将被排除。

$group阶段将根据指定的_id值对文档进行分组,并应用任何指定的累加器表达式。

在您的示例中,这将根据publisher字段的值对文档进行分组,并为组中的每个文档将count字段递增1。

-

顺序确实很重要。

示例

考虑一个包含3个文档的样本数据集:

代码语言:javascript
复制
[
  {_id:1, publisher:"barnes"},
  {_id:2, publisher:"noble"},
  {_id:3, publisher:"barnes"}
]

由于示例管道不是以匹配阶段开始的,因此所有文档都将在开始时位于流中。

然后是项目组和

在您提供的第一个管道中,第一阶段是:

代码语言:javascript
复制
{ $group : { _id : "$publisher" , count:{$sum:1} }  }

在此阶段之后,管道流中的文档将如下所示:

代码语言:javascript
复制
[
  { _id: "barnes", count: 2},
  { _id: "noble", count:1}
]

然后是第二阶段

代码语言:javascript
复制
{$project: { _id:0 , count:1}  }

清除除count之外的所有字段,保留

{count: 2},{count: 1}

项目,然后分组

在您的第二个管道示例中,阶段的顺序是相反的,因此从同一组输入文档开始:

代码语言:javascript
复制
[
  {_id:1, publisher:"barnes"},
  {_id:2, publisher:"noble"},
  {_id:3, publisher:"barnes"}
]

第一阶段

代码语言:javascript
复制
{$project: { _id:0 , count:1}  }

删除除计数之外的所有字段,保留:

代码语言:javascript
复制
[
 {},
 {},
 {}
]

第二阶段

代码语言:javascript
复制
{ $group : { _id : "$publisher" , count:{$sum:1} }  }

groups by _id,此时所有文档中都缺少该值,因此$group将使用null作为值,并将每个文档的计数相加并递增,留下:

代码语言:javascript
复制
[
 { _id:null, count:3}
]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61361137

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档