c# - 聚合和分组

标签 c# mongodb .net-core aggregate

尝试使用我的 .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();

无法找到如何按嵌套数组元素字段(在示例中,Event 中的 IsFake 属性)进行分组以及如何构建我上面共享的结果。 令我惊讶的是我在 google 中找不到很多相关问题..(特别是使用 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数据库之旅。

关于c# - 聚合和分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60173209/

相关文章:

mongodb - elasticsearch mongo-connector卡在 “Logging to mongo-connector.log”中

node.js - 等待 Mongoose 查询完成

.net - .NET 5.0 发布后是否需要 .NET Standard

c# - Socket.SetSocketOption 在 Mac OS 和 Linux 上抛出无效参数异常,但在 Windows 上工作正常

c# - Unity3D 中的 Time.time vs DateTime.UtcNow.Millisecond 性能?

c# - 读取和修改通用 List<T> 中的对象

c# - 如何将 "zip"或 "rotate"列为可变数量的列表?

node.js - 如何将我的 mongoose find 查询转换为 mongoDB 聚合框架?

c# - 如何在 .NET Core 中模拟/ stub HttpRequestMessage?

c# - 从代码覆盖中删除 c__DisplayClass