首页 > 解决方案 > 通过 C# MongoDB 驱动程序聚合查询结果

问题描述

MongoDB 数据库中有两个集合。Department根据以下示例调用一个集合:

{
    "_id": "Dept1",
    "Description": "Department 1",
    "ApplicationName": "Payroll",
    "Version": 1
}

{
    "_id": "Dept2",
    "Description": "Department 2",
    "ApplicationName": "Payroll",
    "Version": 1
}

{
    "_id": "Dept3",
    "Description": "Department 3",
    "ApplicationName": "Payroll",
    "Version": 1
}

调用另一个集合UserAssociation,其数据类似于以下示例:

{
    "_id": "Associate1",
    "DepartmentIds": ["Dept1","Dept2"]
}

{
    "_id": "Associate2",
    "DepartmentIds": ["Dept2","Dept3"]
}

{
    "_id": "Associate3",
    "DepartmentIds": ["Dept1", "Dept2","Dept3"]
}

这两个文档的 C# 模型是:

public class Department
{
    public string Id { get; set; }
    public string Description { get; set; }
    public string ApplicationName { get; set; }
    public int Version { get; set; }
}

public class Associate
{
    public string Id { get; set; }
    public string[] DepartmentIds { get; set; }
}

我想在一天结束时通过聚合或“加入” (任何可以帮助更好的东西)填充以下模型:

public class DepartmentAssociation
{
    public string AssociateId { get; set; }
    public Department[] Departments { get; set; }
}

如何在 C# 中实现这个目标?

标签: c#mongodb

解决方案


您需要将数据聚合到单个文档中,理想情况下这应该在存储点,但是如果您不能这样做,mongo 确实包含查找功能

它的语法是

$lookup:
{
    from: "<collection to join>",
    localField: "<field from the input documents>",
    foreignField: "<field from the documents of the 'from' collection>",
    as: "<output array field>"
}

或者如果你用 c# 编写它

PipelineDefinition<BsonDocument, BsonDocument> pipeline = new BsonDocument[]
{
    new BsonDocument("$lookup", new BsonDocument(){
            {"from", "<collection to join>"},
            {"localField", "<field from the input documents>"},
            {"foreignField", "<field from the documents of the 'from' collection>"},
            {"as", "<output array field>"}
     }
};

using (var cursor = await collection.AggregateAsync(pipeline, options))
{
    while (await cursor.MoveNextAsync())
    {
        var batch = cursor.Current;
        foreach (BsonDocument document in batch)
        {
            Console.WriteLine(document.ToJson());
        }
    }
}

更具体的细节

PipelineDefinition<BsonDocument, BsonDocument> pipeline = new BsonDocument[]
{
    new BsonDocument("$lookup", new BsonDocument(){
            {"from", "Department"},
            {"localField", "DepartmentIds"},
            {"foreignField", "_id"},
            {"as", "Departments"}
     }
};

using (var cursor = await collection.AggregateAsync<DepartmentAssociation>(pipeline, options))
{
    while (await cursor.MoveNextAsync())
    {
        var batch = cursor.Current;
        foreach (DepartmentAssociation document in batch)
        {
            ...
        }
    }
}

推荐阅读