我们有一个文档集合,其架构总结了日常交易。
{
"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
}
}
}
使用 C# MongoDB 驱动程序 v2.21,我们可以使用 Aggregator 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();
尚不清楚我们是否缺少投影阶段,或者我们在
Group
中采取的方法是否不正确。
任何关于如何实现这一目标的指示或参考将不胜感激。
MongoDB 聚合管道应如下所示:
$match
- 过滤阶段
$group
- 按 transactionDay
分组并执行计算。
$group
- 按 licenseId
分组并构建 transactionDays
数组。
$project
- 装饰输出文档。通过 transactionDays
将 $arrayToObject
数组转换为键值对。
[
{
$match: {
"licenseId": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
},
{
$group: {
_id: "$transactionDay",
licenseId: {
$first: "$licenseId"
},
countTotal: {
$sum: "$count"
},
sizeTotal: {
$sum: "$size"
}
}
},
{
$group: {
_id: "$licenseId",
transactionDays: {
$push: {
k: "$_id",
v: {
countTotal: "$countTotal",
sizeTotal: "$sizeTotal"
}
}
}
}
},
{
$project: {
_id: 0,
licenseId: "$_id",
usage: {
$arrayToObject: "$transactionDays"
}
}
}
]
您的预期结果的模型类应如下所示:
[BsonNoId]
public class UsageReport
{
public Guid licenseId { get; set; }
public Dictionary<string, UsageDate> usage { get; set; }
}
public class UsageDate
{
public int countTotal { get; set; }
public int sizeTotal { get; set; }
}
对于 Aggregate Fluent 语法,应如下所示:
PipelineStageDefinition<Transaction, Transaction> firstStage
= PipelineStageDefinitionBuilder.Match(licenseFilter);
PipelineStageDefinition<Transaction, BsonDocument> secondStage
= PipelineStageDefinitionBuilder.Group<Transaction, BsonDocument>(new BsonDocument
{
{ "_id", "$transactionDay" },
{ "licenseId", new BsonDocument
{
{ "$first", "$licenseId" }
}
},
{ "sizeTotal", new BsonDocument
{
{ "$sum", "$size" }
}
},
{ "countTotal", new BsonDocument
{
{ "$sum", "$count" }
}
}
});
PipelineStageDefinition<BsonDocument, BsonDocument> thirdStage
= PipelineStageDefinitionBuilder.Group<BsonDocument, BsonDocument>(new BsonDocument
{
{ "_id", "$licenseId" },
{ "transactionsDays", new BsonDocument
{
{ "$push", new BsonDocument
{
{ "k", "$_id" },
{ "v", new BsonDocument
{
{ "countTotal", "$countTotal" },
{ "sizeTotal", "$sizeTotal" }
}
}
}
}
}
}
});
PipelineStageDefinition<BsonDocument, UsageReport> forthStage
= PipelineStageDefinitionBuilder.Project<BsonDocument, UsageReport>(new BsonDocument
{
{ "_id", 0 },
{ "licenseId", "$_id" },
{ "usage", new BsonDocument("$arrayToObject", "$transactionsDays") }
});
var usageReport = _collection.Aggregate()
.AppendStage(firstStage)
.AppendStage(secondStage)
.AppendStage(thirdStage)
.AppendStage(forthStage)
.ToList();