You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB C# Driver v2.21:将时间桶转换为日期键字典结构

问题描述

我们有一个存储每日交易汇总的MongoDB文档集合,原始Schema如下:

{
  "licenseId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "transactionDay":"2023-08-23",
  "startTime": "2023-08-23T13:00:00Z",
  "endTime": "2023-08-23T13:01:00Z",
  "count": 1,
  "size": 12345
}

需要生成如下格式的报表,将每日的count和size总计以transactionDay为键存入字典结构:

{
  "licenseId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "usage": {
    "2023-08-23": {
      "countTotal": 1,
      "sizeTotal": 12345
    }
  }
}

目前使用MongoDB C# Driver v2.21的聚合Fluent语法,只能生成每日汇总但无法得到目标格式,现有代码如下:

var usageReport = transactionCollection.Aggregate()
    .Match(licenseFilter)
    .Group(
        e => e.transactionDay,
        g => new
        {
            transactionDay= g.Key,
            licenseId= g.First().licenseId,
            sizeTotal= g.Sum(x=>x.size),
            countTotal= g.Sum(x=>x.count)
        })
    .ToList();

不清楚是缺少Projection阶段还是Group方式有误,需要实现该需求的指引。

解决方案

要得到目标格式,核心是调整聚合逻辑的分组层级:先按licenseId分组,在组内整理每日汇总数据并转换为字典结构,具体实现如下:

Fluent语法实现

var usageReport = transactionCollection.Aggregate()
    .Match(licenseFilter)
    // 第一步:按licenseId分组,组内按transactionDay计算每日汇总
    .Group(
        e => e.licenseId,
        g => new
        {
            LicenseId = g.Key,
            DailyUsage = g.Group(x => x.transactionDay, dayGroup => new
            {
                Key = dayGroup.Key,
                Value = new
                {
                    countTotal = dayGroup.Sum(x => x.count),
                    sizeTotal = dayGroup.Sum(x => x.size)
                }
            })
        })
    // 第二步:将每日汇总数组转为字典结构,生成最终格式
    .Project(result => new
    {
        result.LicenseId,
        Usage = result.DailyUsage.ToDictionary(kv => kv.Key, kv => kv.Value)
    })
    .ToList();

原生聚合语法实现(贴近MongoDB原生操作)

var usageReport = transactionCollection.Aggregate()
    .Match(licenseFilter)
    .Group(
        new BsonDocument("_id", "$licenseId"),
        new BsonDocument
        {
            {
                "dailyUsage", new BsonDocument("$push", new BsonDocument
                {
                    { "k", "$transactionDay" },
                    { "v", new BsonDocument
                        {
                            { "countTotal", "$count" },
                            { "sizeTotal", "$size" }
                        }
                    }
                })
            }
        })
    .Project(new BsonDocument
    {
        { "licenseId", "$_id" },
        { "usage", new BsonDocument("$arrayToObject", "$dailyUsage") },
        { "_id", 0 }
    })
    .ToList();

关键说明

  • 原代码的问题在于按transactionDay分组,导致结果是多个按日期拆分的文档,而目标是每个licenseId对应一个整合所有日期汇总的文档。
  • 必须先按licenseId分组,在组内完成每日数据的汇总和结构转换,才能将所有日期的统计结果整合到一个usage字典中。
  • 使用ToDictionary(Fluent语法)或$arrayToObject(原生聚合)是实现字典结构的核心操作。

内容的提问来源于stack exchange,提问作者PeeGee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 09:12:54