猿教程 Logo

.Net连接MongoDb:.NET驱动程序中使用强类型和专用功能的聚合

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

介绍

在上一篇文章中,我们研究了如何使用松散类型的BsonDocument对象和AppendStage函数在MongoDb .NET驱动程序中构建聚合管道。 AppendStage可以接受任何类型的聚合阶段,每个阶段都用简单的字符串描述。 AppendStage的一个优点是我们可以使用它来表达任何类型的聚合阶段,包括那些没有合适的专用功能,如$ redact。

在这篇文章中,我们将看看前面解决方案的强类型替代方案。

专用聚合阶段功能

聚合函数打开一个流畅的API,其中AppendStage只是一个选择。 当你输入...

modelContext.ZipCodes.Aggregate().

...在Visual Studio中,您将看到有许多其他可用的功能是各种阶段的专用版本,如$ match或$ group。

让我们看看我们如何使用它们来重写我们原来的JSON查询:

db.zipcodes.aggregate([
{$group: { "_id" : "$state", "population" : {$sum : "$pop"}}}, 
{$match : {population : {$gte : 5000000}}}, 
{$sort: {"_id" : 1}}, 
{$limit : 5}])

分组

小组阶段是最复杂的阶段,其他是简单的。 组功能有3个重载,第三个是最灵活的,它接受一个ID选择器和分组选择器。 两者都使用LINQ表示。

上述$小组阶段可以表述如下:

ModelContext modelContext = ModelContext.Create(new ConfigFileConfigurationRepository(), new AppConfigConnectionStringRepository());

var result = modelContext.ZipCodes.Aggregate().Group(key => key.State, 
	value => new { State = value.Key, Population = value.Sum(key => key.Population) }).ToList();

foreach (var item in result)
{
	Console.WriteLine(string.Format("{0}: {1}", item.State, item.Population));
}

第一个选择器指定我们要根据邮政编码的状态字段进行分组。 该值将是一个匿名对象,我们指出我们想要返回的值。 首先我们需要的是这个密钥,这将是州和一个人口,这将是邮政编码对象的人口字段的总和。

上述语句返回具有2个属性的匿名对象列表:State和Population。 以下是前5个要素:

MN:4372982 SC:3486703 RI:1003218 OK:3145585 MA:6016425

它看起来很有希望。 当我们在这里,我们也可以讨论如何将匿名对象转换成具体的对象。 通用的扩展方法可以帮助我们。 我们需要一个保存这些属性的对象。 我们还需要告诉MongoDb哪些是Bson元素:

public class ZipCodeGroupResult
{
	[BsonId]
	[BsonElement(elementName: "_id")]
	public string State { get; set; }
	[BsonElement(elementName: "Population")]
	public int Population { get; set; }
}

我们现在可以将上述C#语句重写为以下内容:

var resultWithAsFunction = modelContext.ZipCodes.Aggregate().Group(key => key.State,
	value => new { State = value.Key, Population = value.Sum(key => key.Population) })
	.As<ZipCodeGroupResult>().ToList();
foreach (var item in resultWithAsFunction)
{
	Console.WriteLine(string.Format("{0}: {1}", item.State, item.Population));
}

上述代码将产生完全相同的输出。

我们甚至可以在ToList()之后使用标准的选择LINQ方法来将匿名对象映射为“真实的”对象。 在这种情况下,我们甚至不需要ZipCodeGroupResult类中的Bson相关属性:

var resultWithSelectExtension = modelContext.ZipCodes.Aggregate().Group(key => key.State,
	value => new { State = value.Key, Population = value.Sum(key => key.Population) }).ToList()
	.Select(z => new ZipCodeGroupResult() { Population = z.Population, State = z.State });

其他阶段

其他阶段很简单,可以通过其功能名称轻松找到。 以下是返回匿名对象列表的解决方案:

var fullQueryResultAnon = modelContext.ZipCodes.Aggregate().Group(key => key.State,
	value => new { State = value.Key, Population = value.Sum(key => key.Population) })
	.Match(z => z.Population > 5000000)
	.SortBy(z => z.State)
	.Limit(5)
	.ToList();
foreach (var item in fullQueryResultAnon)
{
	Console.WriteLine(string.Format("{0}: {1}", item.State, item.Population));
}

它产生与上述纯JSON解决方案相同的结果:

CA:29754890 FL:12686644 GA:6478216 IL:11427576 IN:5544136

As扩展函数仍然可以用于将匿名对象映射到具体的对象:

var fullQueryResultConcrete = modelContext.ZipCodes.Aggregate().Group(key => key.State,
				value => new { State = value.Key, Population = value.Sum(key => key.Population) })
				.Match(z => z.Population > 5000000)
				.SortBy(z => z.State)
				.Limit(5)
				.As<ZipCodeGroupResult>()
				.ToList();

这是本系列中MongoDb聚合框架的最后一篇文章。 我们已经看到了最重要的查询类型,包括CRUD操作和聚合。

下一篇文章将开始略有不同的主题,即索引。

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


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