目录
开始之前的注意事项
安装
运行项目
在MongoDb中使用GroupBy
有关MongoDb中聚合的更多信息
MongoDb支持Jion
使用Javascript访问WebApi
您可能也有兴趣
每当您需要创建指标或从数据中获取更多见解时,数据聚合都将非常有用。此外,加入多个MongoDb集合可能会提供更有意义的结果。本文将简要介绍如何使用.NET Driver和LINQ在MongoDb上运行它们。
开始之前的注意事项
本文是第三篇文章,继续第1部分:如何搜索旅行的好地方(MongoDb LINQ和.NET Core)和第2部分:MongoDB中的分页–如何真正避免性能下降?。所有这些共享同一个GitHub项目,每个人都有特定的代码方法。请遵循第1部分中介绍的有关如何安装和配置MongoDb的步骤,以及有关初始数据上传的部分。
安装
这是所有需要安装的东西:
- Visual Studio Community 2017,包括.NET Core选项
- MongoDB和Robomongo
运行项目
简而言之,一旦完成MongoDb的安装,请运行以下步骤:
- 克隆或下载项目(https://github.com/fpetru/WebApiQueryMongoDb)
- 从Data\Import文件夹运行import.cmd
- 在Visual Studio中打开解决方案,进行编译并运行
在MongoDb中使用GroupBy
MongoDb长期以来一直具有一个聚合框架以及.NET驱动程序,其功能非常适合标准LINQ运算符(例如:$project => Select(), $limit => Take(), $match => Where() 等)。LINQ非常适合建立操作流水线并作为单个命令提交到服务器。
在我们的示例中,按City分组,然后找到所有可用的旅行项目,如下所示:
public async Task<IEnumerable<object>> GetTravelDestinations(string cityName)
{
var groupTravelItemsByCity = _context.TravelItems.AsQueryable()
.Where(city => string.IsNullOrEmpty(cityName)
|| city.City.Contains(cityName))
.GroupBy(s => new { s.City })
.Select(n => new
{
value = n.Key.City,
data = n.Count()
});
return await groupTravelItemsByCity.Take(100).ToListAsync();
}
使用控制器的Get函数,结果可用于外部应用程序:
// GET api/Display/GroupBy?city=CityName
[NoCache]
[HttpGet("{type}")]
public async Task<IActionResult> Get(string type, [FromQuery]string city)
{
if (!string.IsNullOrEmpty(city) && city.Length > 1)
return Ok(await _displayRepository.GetTravelDestinations(city));
return NotFound();
}
我已使用IActionResult接口以在请求不符合要求的情况下能够返回404:需要提供city,且长度至少为2个字符。
有关MongoDb中聚合的更多信息
支持所有标准LINQ to SQL聚合运算符:平均值,计数,最大值,最小值和求和。我们还可以使用更多属性进行分组。这是一个示例,首先在City之后分组,然后在每个相关的Action之后分组,还使用聚合函数(例如Count,Max和Min)进行分组:
public async Task<IEnumerable<object>> GetTravelItemStat()
{
var groupTravelItemsByCityAndAction = _context.TravelItems.AsQueryable()
.Where(s => s.City == "Paris" || s.City == "Berlin")
.GroupBy(s => new { s.City, s.Action })
.Select(n => new
{
Location = n.Key,
Count = n.Count(),
MaxPrice = n.Max(p => p.Price),
MinPrice = n.Min(p => p.Price)
});
return await groupTravelItemsByCityAndAction.Take(100).ToListAsync();
}
MongoDb支持Jion
这是一个使用LINQ作为查询表达式在两个集合之间运行联接的示例。这是一个LEFT 联接查询,从第一个(最左侧)集合(TravelItems)开始,然后匹配第二个(最右侧)集合(CityExtended)。
这意味着它将过滤结果项(CityExtended)。总体结果可以以匿名类型(我们的以下示例)或新实体进行投影:
public async Task<IEnumerable<object>> GetTravelItemsOfCityAsync(string cityName)
{
var query = from travelItem in _context.TravelItems.AsQueryable()
join city in _context.CityExtended.AsQueryable()
on travelItem.City equals city.Name
into CityExtendedMatchingItems
where (travelItem.City == cityName)
select new
{
Action = travelItem.Action,
Name = travelItem.Name,
FirstCityMatched = CityExtendedMatchingItems.First(),
};
return await query.Take(10).ToListAsync();
}
使用Javascript访问WebApi
使用javascript从简单的静态HTML访问webapi可能看起来像这样:
为了使项目中的html文件可用,我们首先需要启用对静态文件(例如html,css,图像)的访问。这些通常位于web根目录(/wwwroot)文件夹。对于开发,我们可以将其设置为项目的Web根目录-参见方法(UseContentRoot):
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();
为了提供静态文件,我们还需要配置中间件以将静态文件添加到管道中。
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// ...
app.UseStaticFiles();
// ...
}
启用静态文件后,我们将使用jQuery库访问WebApi,并显示结果(带有自动完成的小部件)。该代码最初可从以下网址获得:https : //designshack.net/articles/javascript/create-a-simple-autocomplete-with-html5-jquery。
这是自动完成功能和WebApi服务器调用的完整javascript代码。
<script type="text/javascript">
$(document).ready(function () {
$('#autocomplete').autocomplete({
minLength: 2,
source: function (request, response) {
var webApiUrl = './api/display/GroupBy' + '?city=' + request.term;
$.getJSON(webApiUrl, request, function (data, status, xhr) {
response(data);
});
},
});
});
</script>