猿教程 Logo

.Net连接MongoDb:聚合(续)

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

介绍

在上一篇文章中,我们看了我们的第一个聚合示例。 我们按照状态和每个州的居民人数对邮政编码集合进行分组。 分组阶段由$ group运算符表示,后面跟着多个参数。 我们经历了MongoDb执行的过程,以生成最终的文档集。 本质上它对起始集合执行一系列的upsert操作。

在这篇文章中,我们将看一些其他的查询示例。

按国家计算平均人口

$ avg运算符指示MongoDb计算数字字段的平均值。 查询几乎与上一篇文章中看到的$ sum查询相同:

db.zipcodes.aggregate([{"$group":{"_id":"$state", "population":{$avg:"$pop"}}}])

以下是输出的一部分:

{ "_id" : "MN", "population" : 4958.02947845805 }
{ "_id" : "SC", "population" : 9962.00857142857 }
{ "_id" : "RI", "population" : 14539.391304347826 }
{ "_id" : "OK", "population" : 5367.892491467577 }
{ "_id" : "MA", "population" : 12692.879746835442 }
{ "_id" : "SD", "population" : 1810.9296875 }

复合ID

上述输出中的_id字段可能不是不言自明的。 什么是MN和RI和其他代码? 对于一些人来说,这将是显而易见的,但有些人可能会怀疑。 我们可以通过将一个子文档分配给_id字段来清楚,如下所示:

db.zipcodes.aggregate([{"$group":{"_id":{"us_state": "$state"}, "population":{$sum:"$pop"}}}])

以下是输出的一部分:

{ "_id" : { "us_state" : "MN" }, "population" : 4372982 }
{ "_id" : { "us_state" : "SC" }, "population" : 3486703 }
{ "_id" : { "us_state" : "RI" }, "population" : 1003218 }
{ "_id" : { "us_state" : "OK" }, "population" : 3145585 }
{ "_id" : { "us_state" : "MA" }, "population" : 6016425 }

我们可以以任何我们想要的方式在_id子文档中命名关键字。 复合_id字段对于复合分组阶段以及本文后面的内容也将是重要的。

计算最小和最大

根据国家,人口最少和最多的地方如何? 满足$ min和$ max运算符。 以下是$ max的示例:

db.zipcodes.aggregate([{"$group":{"_id":"$state", "max_pop":{$max:"$pop"}}}])

以下是输出的一部分:

{ "_id" : "MN", "max_pop" : 51421 }
{ "_id" : "SC", "max_pop" : 66990 }
{ "_id" : "RI", "max_pop" : 53733 }
{ "_id" : "OK", "max_pop" : 45542 }
{ "_id" : "MA", "max_pop" : 65046 }

没有什么可以阻止我们添加更多的聚合运算符,例如在下面的示例中,我们同时显示最小和最大值:

db.zipcodes.aggregate([{"$group":{"_id":"$state", "max_pop":{$max:"$pop"}, "min_pop": {"$min" : "$pop"}}}])

...其结果如下:

{ "_id" : "NY", "max_pop" : 111396, "min_pop" : 0 }
{ "_id" : "DE", "max_pop" : 50573, "min_pop" : 108 }
{ "_id" : "DC", "max_pop" : 62924, "min_pop" : 11 }
{ "_id" : "OR", "max_pop" : 48007, "min_pop" : 0 }
{ "_id" : "MD", "max_pop" : 76002, "min_pop" : 1 }

将数值提取到数组中

这次我们在餐厅收藏品尝试一下。 我们想要通过自治市镇找到独特的美食类型,例如 什么类型的曼哈顿餐厅提供。 $ addToSet操作符在这里被我们看到的操作起到了作用。 它为数组添加唯一的值,这是查询:

db.restaurants.aggregate([{"$group":{"_id":"$borough", "cuisine_types":{$addToSet:"$cuisine"}}}])

这是Staten岛自治市镇的一部分:

{ "_id" : "Staten Island", "cuisine_types" : [ "Italian", "Ice Cream, Gelato, Yogurt, Ices", "Jewish/Kosher", "Armenian", "Pizza/Italian", "Peruvian", "Fruits/Vegetables", "Delicatessen", "American ", "Russian", "Hamburgers", "Chinese", "Spanish", "Barbecue", "Pizza", "Hotdogs/Pretzels", "Japanese", "Donuts", "Bagels/Pretzels", "Korean", "Indian", "Bakery", "Café/Coffee/Tea", "Juice, Smoothies, Fruit Salads", "German", "Mexican", "Irish", "Chicken", "Sandwiches", "Caribbean", "Cajun", "French", "Mediterranean", "Chinese/Japanese", "Seafood", "Latin (Cuban, Dominican, Puerto Rican, South & Central American)", "Pancakes/Waffles", "Hotdogs", "Turkish", "Sandwiches/Salads/Mixed Buffet", "Tex-Mex", "Thai", "Southwestern", "Middle Eastern", "Continental", "Filipino", "Asian", "Bottled beverages, including water, sodas, juices, etc.", "Soups", "Steak", "Other", "Eastern European", "African", "Not Listed/Not Applicable", "Portuguese", "Polish" ] }

另一个例子是如果我们要提取每个城市的独特邮政编码:

db.zipcodes.aggregate([{"$group":{"_id":"$city", "postal_codes":{$addToSet:"$_id"}}}])

以下是一个简单的示例输出:

{ "_id" : "OTIS", "postal_codes" : [ "01253", "71466", "80743", "97368" ] }
{ "_id" : "BARRE", "postal_codes" : [ "01005", "05641" ] }
{ "_id" : "NANTY GLO", "postal_codes" : [ "15943" ] }
{ "_id" : "BIRCH HARBOR", "postal_codes" : [ "04613" ] }
{ "_id" : "COEYMANS HOLLOW", "postal_codes" : [ "12046" ] }
{ "_id" : "HOLYOKE", "postal_codes" : [ "55749", "01040", "80734" ] }

你记得$ push操作符吗? 它类似于$ addToSet,但它也向数组添加了非唯一值。 事实上,上述示例可以用$ push重写,因为所有邮政编码文件都具有唯一的邮政编码ID,因此在“postal_codes”数组中没有结束复制记录的可能性。 这是$ push的解决方案:

db.zipcodes.aggregate([{"$group":{"_id":"$city", "postal_codes":{$push:"$_id"}}}])

它将生成与$ addToSet解决方案相同的一组文档。

复合聚合

我们可以按照标准SQL中的多个项目进行分组。 我们上面看到的复合_id技术是构建复合分组密钥的关键。 假设我们想通过自治市镇和美食组合餐厅,看看每个组合有多少个餐馆,例如 皇后区有多少个“汉堡”餐厅?

db.restaurants.aggregate([{$group : {_id : {"borough" : "$borough", "cuisine":"$cuisine"}, "restaurants_count" : {"$sum" : 1}}}])

以下是一些示例输出:

{ "_id" : { "borough" : "Brooklyn", "cuisine" : "Soups & Sandwiches" }, "restaurants_count" : 5 }
{ "_id" : { "borough" : "Brooklyn", "cuisine" : "Hamburgers" }, "restaurants_count" : 102 }
{ "_id" : { "borough" : "Queens", "cuisine" : "Pakistani" }, "restaurants_count" : 11 }
{ "_id" : { "borough" : "Manhattan", "cuisine" : "Chinese" }, "restaurants_count" : 510 }

到目前为止,在本系列的这一部分中,我们只看到一个单一阶段的简单流水线。 然而,它被称为管道,因为它可以扩展多个阶段。 您可能已经注意到,单个分组阶段包含在我们提供给聚合函数的数组中。 该阵列当然可以延伸到其他阶段。

我们将在下一篇文章中继续讨论多个阶段和其他阶段类型。

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


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