如何在MongoDB中的文档内聚合数组并获取多个条件的计数?

我正在编写一个程序,该程序接收车辆刷新数据的XML文件并将其转换为JSON,以便将其存储在MongoDB数据库中。 XML的开头是这样的:

  PASSED   PASSED   

在我将其转换为JSON并添加项目标识符之后,我留下了一个像这样的格式:

 { "FlashReportGeneratorAddedTag" : { "VehicleEntry" : [ { "VehicleStatus" : "PASSED" }, { "VehicleStatus" : "PASSED" } ] }, "project_id" : "1234" } 

我想做的是获得项目1234的每个文件中通过的车辆总数和车辆数量的总数,但我没有运气。

我已经尝试过使用我所知道的基本聚合技能,但我不能简单地按project_id进行分组,因为当我需要聚合其中的数组时,它会按文档分组。 我还没有找到任何资源告诉你是否可以或不能一次聚合两个值(获得传递的总和和失败计数的总和)。

作为最后的手段,我可​​以改变文档样式,让每个VehicleEntry都是它自己的文档,但是如果可以的话,我想采用并存储XML。

编辑使用Unwind我能够为我正在寻找的数组设置聚合:

 var aggregate = collection.Aggregate().Match(new BsonDocument { { "project_id", "1234" } }).Unwind(i => i["FlashReportGeneratorAddedTag.VehicleEntry"]); 

但是,我找不到合适的方法对这些进行分组,以便在整个arrays中获得通过/失败计数。 我假设有一些方法我需要使用匹配function,但我不知道如何做到这一点,而不排除这两个条件之一。 我是否必须运行聚合两次,一次是传递,一次是失败?

感谢JohnnyHK的暗示以及更多的挖掘,我能够解决这个问题。 首先,我必须使用Unwind方法来展开Vehicleentry数组,以便在其上聚合:

 var aggregate = collection.Aggregate().Match(new BsonDocument { { "project_id", "1234" } }) .Unwind(i => i["FlashReportGeneratorAddedTag.VehicleEntry"]) 

有一次,我能够嵌套BsonDocuments ,以便根据条件求和。 为了得到通过的计数,我使用了这个:

 { "passed", new BsonDocument { { "$sum", new BsonDocument { { "$cond", new BsonArray { new BsonDocument { { "$eq", new BsonArray { "$FlashReportGeneratorAddedTag.VehicleEntry.VehicleStatus", "PASSED" } } }, 1, 0 } } } } } } 

同样,我添加了一个失败的标签。 整件事(尚未格式化)是这样的:

 var collection = _database.GetCollection(Vehicles); var aggregate = collection.Aggregate() .Match(new BsonDocument{ { "project_id", "1234" } }) .Unwind(i => i["FlashReportGeneratorAddedTag.VehicleEntry"]) .Group(new BsonDocument { { "_id", "$project_id" }, { "passed", new BsonDocument { { "$sum", new BsonDocument { { "$cond", new BsonArray { new BsonDocument { { "$eq", new BsonArray { "$FlashReportGeneratorAddedTag.VehicleEntry.VehicleStatus", "PASSED" } } }, 1, 0 } } } } } }, { "failed", new BsonDocument { { "$sum", new BsonDocument { { "$cond", new BsonArray { new BsonDocument { { "$eq", new BsonArray { "$FlashReportGeneratorAddedTag.VehicleEntry.VehicleStatus", "FAILED" } } }, 1, 0 } } } } } }, }); var results = await aggregate.ToListAsync();