我不小心尝试在publis集合上执行两个聚合命令:
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} } } ])你能告诉我这个聚合函数是如何工作的吗?
发布于 2020-04-22 17:38:35
聚合将从输入集合中读取文档,然后沿着管道依次传递文档。stages可以从流中删除文档、创建新文档或修改现有文档。
项目
$project阶段选择要包括在文档中或从文档中排除的字段,并且可以使用运算符生成新值。
在您的示例中,_id:0告诉它在传递文档之前删除_id字段,count:1告诉它包含count字段。
因为您已经显式包含了一个字段,所以所有未提及的字段都将被排除。
组
$group阶段将根据指定的_id值对文档进行分组,并应用任何指定的累加器表达式。
在您的示例中,这将根据publisher字段的值对文档进行分组,并为组中的每个文档将count字段递增1。
-
顺序确实很重要。
示例
考虑一个包含3个文档的样本数据集:
[
{_id:1, publisher:"barnes"},
{_id:2, publisher:"noble"},
{_id:3, publisher:"barnes"}
]由于示例管道不是以匹配阶段开始的,因此所有文档都将在开始时位于流中。
然后是项目组和
在您提供的第一个管道中,第一阶段是:
{ $group : { _id : "$publisher" , count:{$sum:1} } }在此阶段之后,管道流中的文档将如下所示:
[
{ _id: "barnes", count: 2},
{ _id: "noble", count:1}
]然后是第二阶段
{$project: { _id:0 , count:1} }清除除count之外的所有字段,保留
{count: 2},{count: 1}
项目,然后分组
在您的第二个管道示例中,阶段的顺序是相反的,因此从同一组输入文档开始:
[
{_id:1, publisher:"barnes"},
{_id:2, publisher:"noble"},
{_id:3, publisher:"barnes"}
]第一阶段
{$project: { _id:0 , count:1} }删除除计数之外的所有字段,保留:
[
{},
{},
{}
]第二阶段
{ $group : { _id : "$publisher" , count:{$sum:1} } }groups by _id,此时所有文档中都缺少该值,因此$group将使用null作为值,并将每个文档的计数相加并递增,留下:
[
{ _id:null, count:3}
]https://stackoverflow.com/questions/61361137
复制相似问题