c# - 聚合和分组
问题描述
尝试使用我的 .NET Core 项目对我的 MongoDB 集合进行一些分析。(C# 驱动程序)
我的问题是按多个字段以及嵌套数组元素字段进行聚合和分组。
对于初学者来说,这是我可以记录示例的简化 -
{
"_id": ".....",
"CampaignId": 1,
"IsTest":false
"Events": [
{
"EventId": 1,
"IsFake": false
},
{
"EventId": 1,
"IsFake": true
}
{
"EventId": 2,
"IsFake": false
}
]
}
我的最终目标是生成一个如下所示的分析报告 -
[
{
"CampaignId": 1,
"DocumentCountReal":17824,
"DocumentCountTest":321,
"EventCountReal":100,
"EventCountFake":5,
"Events": [
{
"EventId": 1,
"IsFake": false,
"Count": 50
},
{
"EventId": 1,
"IsFake": true,
"Count": 5
},
{
"EventId": 2,
"IsFake": false,
"Count": 50
}
]
},
{
"CampaignId": 2,
"DocumentCountReal":1314,
"DocumentCountTest":57,
"EventCountReal":50,
"EventCountFake":0,
"Events": [
{
"EventId": 1,
"IsFake": false,
"Count": 25
},
{
"EventId": 2,
"IsFake": false,
"Count": 25
}
]
}
]
只是为了向您展示我目前的立场,我发现了如何按一个字段分组哈哈......示例 -
var result = collection.Aggregate().Group(c => c.CampaignId, r => new { CampaignId= r.Key, Count = r.Count()}).ToList();
找不到如何按嵌套数组元素字段(在示例IsFake
中为 Event 中的属性)进行分组,并且通常构建我上面分享的结果。令我惊讶的是,我在谷歌中找不到很多相关的问题..(特别是使用 c# 驱动程序)
非常感谢阅读
解决方案
所以,最终找到了一个部分解决方案,我想我会分享 - 最大的问题是按嵌套数组的属性进行分组(在我最初的问题中,它是事件数组)。为了实现这一点,我使用了 Unwind ( https://docs.mongodb.com/manual/reference/operator/aggregation/unwind/ ) 仅供参考 - 我需要使用 PreserveNullAndEmptyArrays 选项,以免错过没有事件的文档。另外,我做了一个额外的类,其中Events
属性是单个事件而不是列表,即在使用 Uwind 后反序列化文档。
我的第二个问题是如何在一次访问数据库中执行多个聚合,正如 Valijon 评论的那样,它看起来$facet
是必需的,找不到适合我问题的示例。
我的解决方案示例 -
IMongoDatabase db = MongoDBDataLayer.NewConnection();
IMongoCollection<Click> collection = db.GetCollection<Click>("click");
var unwindOption = new AggregateUnwindOptions<ClickUnwinded>() { PreserveNullAndEmptyArrays = true };
var result = collection.Aggregate().Unwind<Click, ClickUnwinded>(c => c.Events, unwindOption)
.Group(
//group by
c => new GroupByClass()
{
CampaignId = c.CampaignId,
IsTest = c.IsTest,
EventId = c.Events.EventId,
IsRobot = c.UserAgent.IsRobot
},
r => new GroupResultClass()
{
CampaignId = r.First().CampaignId,
IsTest = r.First().IsTest,
EventId = r.First().Events.EventId,
IsRobot = r.First().UserAgent.IsRobot,
Count = r.Count()
}
).ToList();
如果有人有一个如何使用 c# 驱动程序来利用 facet 的例子,那就太好了。
编辑 - 所以,问题是,如果文档有多个事件,则执行上述方法将多次计算同一个文档......所以我必须找到一种方法来进行多重聚合(第一次聚合必须在展开之前发生)或去数据库 2 次。
推荐阅读
- python-3.x - 如何按奇数长度分割字符串
- javascript - 无法理解 firebase 中的 doc().get()
- crystal-lang - 当 TZ=":/etc/localtime" 时获取当地时间的正确方法是什么?
- javascript - 为什么我的决心不等待指定的时间?
- javers - 当我使用 Javers 区分对象时,如何获得正确的“PropertyName”
- javascript - 如何遍历数字数组以查找数组中出现 3 次的第一个数字
- mysql - 为什么当我使用像“select * from table_name where character='⺎'”这样的选择语句然后返回'尤','⼪','⺎'和'⺐'
- java - 带有反向代理的 Spring SAML - 响应的 inresponsetofield 与发送的消息不对应
- android - Android:OAuth 客户端已删除
- python - 如何将多个python文件编译成一个android应用程序