C# 如何在MongoDB中聚合文档中的数组,并获得多个条件的计数?

C# 如何在MongoDB中聚合文档中的数组,并获得多个条件的计数?,c#,json,xml,mongodb,aggregation-framework,C#,Json,Xml,Mongodb,Aggregation Framework,我正在编写一个程序,它接收车辆刷新数据的XML文件,并将其转换为JSON,以便将其存储在MongoDB数据库中。XML的开头是这样的: <FlashReportGeneratorTag> <VehicleEntry> <VehicleStatus>PASSED</VehicleStatus> </VehicleEntry> <VehicleEntry> <Vehi

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

<FlashReportGeneratorTag>
    <VehicleEntry>
        <VehicleStatus>PASSED</VehicleStatus>
    </VehicleEntry>
    <VehicleEntry>
        <VehicleStatus>PASSED</VehicleStatus>
    </VehicleEntry>
</FlashReportGeneratorTag>
{
    "FlashReportGeneratorAddedTag" : {
        "VehicleEntry" : [
            {
                "VehicleStatus" : "PASSED"
            }, 
            {
                "VehicleStatus" : "PASSED"
            }
        ]
    },
    "project_id" : "1234"
}
var collection = _database.GetCollection<BsonDocument>(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();
我想做的是在项目1234的每个文档中获得通过车辆数和失败车辆数的合计计数,但我没有运气

我尝试过使用我知道的基本聚合技能,但我不能简单地按项目id分组,因为当我需要在其中的数组上聚合时,这将按文档分组。我还没有找到任何资源可以告诉您是否可以同时聚合两个值(获取通过计数和失败计数之和)

作为最后一种手段,我可以改变文档样式,使每个VehicleEntry都成为自己的文档,但如果可以的话,我希望按原样获取和存储XML

编辑使用“展开”,我能够为我要查找的阵列设置聚合:

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

但是,我找不到正确的方法对这些数据进行分组,以获得整个阵列的通过/失败计数。我假设有某种方法需要使用Match函数,但如果不排除这两个条件中的一个,我就不知道如何使用Match函数。我是否必须运行聚合两次,一次用于通过,一次用于失败?

多亏了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 } } } } } }
类似地,我添加了一个失败的选项卡。整个过程(尚未格式化)是这样的:

<FlashReportGeneratorTag>
    <VehicleEntry>
        <VehicleStatus>PASSED</VehicleStatus>
    </VehicleEntry>
    <VehicleEntry>
        <VehicleStatus>PASSED</VehicleStatus>
    </VehicleEntry>
</FlashReportGeneratorTag>
{
    "FlashReportGeneratorAddedTag" : {
        "VehicleEntry" : [
            {
                "VehicleStatus" : "PASSED"
            }, 
            {
                "VehicleStatus" : "PASSED"
            }
        ]
    },
    "project_id" : "1234"
}
var collection = _database.GetCollection<BsonDocument>(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();
var collection=\u database.GetCollection(车辆);
var aggregate=collection.aggregate()
.Match(新的BsonDocument{{“project_id”,“1234”})
.展开(i=>i[“FlashReportGeneratorAddedTag.VehicleEntry”])
.组(新的B文档)
{ 
{“\u id”,“$project\u id”},
{“通过”,新的B文件
{{“$sum”,新的B文件
{{“$cond”,新的BsonArray
{新文件
{{“$eq”,新的BsonArray
{
“$FlashReportGeneratorAddedTag.VehicleEntry.VehicleStatus”,
“通过”
} }
},
1.
0 } } } } } 
},
{“失败”,新的BsonDocument
{{“$sum”,新的B文件
{{“$cond”,新的BsonArray
{新文件
{{“$eq”,新的BsonArray
{
“$FlashReportGeneratorAddedTag.VehicleEntry.VehicleStatus”,
“失败”
} }
},
1.
0 } } } } } 
},
});
var results=await aggregate.ToListAsync();

您是否考虑过使用?@JohnnyHK我没有,但它看起来很有希望,让我来玩玩这个想法,我认为我可以让它发挥作用。@JohnnyHK Unwind确实起作用,但我仍然面临聚合两个条件的问题,如果您认为您有想法,请查看我的编辑。@JohnnyHK很抱歉第三次ping,但我成功了。我会马上分享我自己的答案。@JohnnyHK我会尽我最大的努力,但它扩展得非常大。我会尽量保持它干净。我想问你另一个问题,因为我似乎是在逃避责任。这只适用于一个文档,但如果我有两个项目“1234”文档,我似乎无法将每个文档相加为一个最终结果文档。