猿教程 Logo

.Net连接MongoDb:向聚合管道添加多个阶段

阿里云服务器,每月低至7.8元,项目演示即建站必备,比腾讯云更便宜,并且不需学生认证,从此链接购买有效:去购买

介绍

在上一篇文章中,我们继续讨论MongoDb聚合管道中的分组阶段。 我们查看了一些可用于聚合的$运算符,例如$ min,$ avg和$ addToSet。 我们还看到如何使用复合ID来添加多个分组密钥。 当我们要给强制性的_id属性给出一个解释性字段时,复合ID也是有用的,因此清楚分组密钥是什么。

在这篇文章中,我们将开始为管道添加多个阶段。 到目前为止,我们已经有一个阶段的简单聚合管道,但没有什么阻止我们添加更多的舞台数组。 也可以添加相同阶段类型的多个实例。

投影

投影可以将文件重塑成各种形式。 我们可以添加新的属性,删除不需要的属性,转换子文档,以便以更简单的方式聚合。 投影阶段由$ project运算符表示。 请记住,投影根本不会修改源文档。 它将在内存中创建新的文档,并将它们传递到下一个阶段,如果有的话。

我们从一个简单的例子开始,并转换一下邮政编码文件:

db.zipcodes.aggregate([{$project:{_id:0, city:{$toLower:"$city"}, pop:1, state:1, zip:"$_id"}}])
  • _id:0表示我们不想在结果集中显示_id字段

  • $ toLower:这将字符串中的每个字符放入小写。 有一个相应的$ toUpper运算符

  • pop:1和state:1表示我们想保留源文档中的这些字段

  • zip:“$ _id”表示我们要将_id字段重命名为zip

以下是一个示例输出:

{ "city" : "agawam", "pop" : 15338, "state" : "MA", "zip" : "01001" }
{ "city" : "cushman", "pop" : 36963, "state" : "MA", "zip" : "01002" }
{ "city" : "belchertown", "pop" : 10579, "state" : "MA", "zip" : "01007" }
{ "city" : "blandford", "pop" : 1240, "state" : "MA", "zip" : "01008" }
{ "city" : "barre", "pop" : 4546, "state" : "MA", "zip" : "01005" }

现在是展示第一个扩展管道的时候了。 我们将在投影阶段之后添加一个分组阶段。 重要的一点是,分组阶段将返回到之前的阶段的文档中的属性,即投影。 以下是邮编的平均人数:

db.zipcodes.aggregate([{$project:{_id:0, city:{$toLower:"$city"}, pop:1, state:1, zip:"$_id"}}, {$group : {_id : {"zipcode" : "$zip"}, "average_pop" : {$avg : "$pop"} }}])

请注意我们如何引用到组阶段中的预计zip字段来构建复合ID并显示分组键的含义。

过滤

我们不想在聚合中包含所有文档。 $ match聚合阶段的工作方式类似于我们如何使用JSON(JSON)文档作为过滤器来使用find()函数。

下一个示例将过滤出邮编小于50k的邮政编码集合中的位置:

db.zipcodes.aggregate([{$match:{pop:{$gte:50000}}}])

我们还将转换这些文件:

db.zipcodes.aggregate([{$match:{pop:{$gte:50000}}}, {$project:{_id:0, city:{$toLower:"$city"}, pop:1, state:1, zip:"$_id"}}])

...最后我们可以对他们进行分组,这意味着我们将对人口超过5万的地方进行分组,并计算其平均人口数量:

db.zipcodes.aggregate([
{$match:{pop:{$gte:50000}}}, 
{$project:{_id:0, city:{$toLower:"$city"}, pop:1, state:1, zip:"$_id"}},
{$group : {_id : {"zipcode" : "$zip"}, "average_pop" : {$avg : "$pop"}}}
])

在更复杂的聚合查询中,眼睛跟随所有这些花括号可能会有点困难。 这三个阶段仍然很简单。

这种模块化设置的好处是您可以逐步构建您的聚合管道,并在Mongo客户端中查看部分结果。

排序

我们还可以使用$ sort聚合阶段对最终结果进行排序。 再次,它类似于我们如何在Mongo shell中进行排序,然后使用1进行升序,-1按降序排序:

db.zipcodes.aggregate([
{$match:{pop:{$gte:50000}}}, 
{$project:{_id:0, city:{$toLower:"$city"}, pop:1, state:1, zip:"$_id"}},
{$group : {_id : {"city_name" : "$city"}, "average_pop" : {$avg : "$pop"}}},
{$sort: {"_id.city_name" : 1}}
])

请注意,我们如何使用我们之前看到的点符号从分拣阶段将回归到city_name的分组阶段的复合ID。

按城市名称排列的结果的一部分按升序排列:

{ "_id" : { "city_name" : "aiken" }, "average_pop" : 51233 }
{ "_id" : { "city_name" : "albuquerque" }, "average_pop" : 50233 }
{ "_id" : { "city_name" : "alhambra" }, "average_pop" : 51148 }
{ "_id" : { "city_name" : "allentown" }, "average_pop" : 59074 }
{ "_id" : { "city_name" : "alton" }, "average_pop" : 67604 }

限制和跳过

我们当然可以像在过滤搜索函数中的结果一样对结果集进行限制和跳过。 它们由$ limit和$ skip运算符表示,并且都接受整数值:

db.zipcodes.aggregate([
{$match:{pop:{$gte:50000}}}, 
{$project:{_id:0, city:{$toLower:"$city"}, pop:1, state:1, zip:"$_id"}},
{$group : {_id : {"city_name" : "$city"}, "average_pop" : {$avg : "$pop"}}},
{$sort: {"_id.city_name" : 1}},
{$skip: 10},
{$limit: 5} 
])

这是与上述相同的查询,但我们跳过前十个文档,并选择最多5.以下是结果集:

{ "_id" : { "city_name" : "arlington height" }, "average_pop" : 52947 }
{ "_id" : { "city_name" : "aspen hill" }, "average_pop" : 52694 }
{ "_id" : { "city_name" : "atlanta" }, "average_pop" : 53894 }
{ "_id" : { "city_name" : "aurora" }, "average_pop" : 51422 }
{ "_id" : { "city_name" : "azusa" }, "average_pop" : 52261 }

我们将使用上述操作符的最终示例关闭此帖子。 我们希望对纽约州的所有城市进行整理,总结人口。 然后我们将文档投影到更整洁的结果集中,按照人口按降序对文档进行排序,跳过前10个文档,并将结果集限制为5个文档:

db.zipcodes.aggregate([
    {$match:
     {
	 state:"NY"
     }
    },
    {$group:
     {
	 _id: "$city",
	 population: {$sum:"$pop"},
     }
    },
    {$project:
     {
	 _id: 0,
	 city: "$_id",
	 population: 1,
     }
    },
    {$sort:
     {
	 population:-1
     }
    },    
    {$skip: 10},
	{$limit: 5}
])

结果如下:

{ "population" : 165629, "city" : "ASTORIA" }
{ "population" : 145967, "city" : "JACKSON HEIGHTS" }
{ "population" : 100646, "city" : "FAR ROCKAWAY" }
{ "population" : 85732, "city" : "RIDGEWOOD" }
{ "population" : 83017, "city" : "BINGHAMTON" }

我们将在下一篇文章中看到更多的聚合阶段类型。

阿里云服务器,每月低至7.8元,项目演示即建站必备,比腾讯云更便宜,并且不需学生认证,从此链接购买有效: 去购买


版权声明:本站所有教程均为本站原创或翻译,转载请注明出处,请尊重他人劳动果实。请记住本站地址:www.yuanjiaocheng.net (猿教程) 作者:卿文刚
本文标题: C#环境
本文地址:http://www.yuanjiaocheng.net/CsharpMongo/25.html