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

MongoDB 6.0文档结构转换求助:$unwind和$group未达预期结果

MongoDB 文档结构转换方案

原始文档结构

[
    {
        "_id" : ObjectId("6555a7d7c2d9de74abb09de8"),
        "tagName" : "tag1",
        "tagValue" : "value1",
        "categories" : ["Category-1"],
        "otherField1" : [],
        "otherField2" : "something-else-1"
    },
    {
        "_id" : ObjectId("6555a865c2d9de74abb09de9"),
        "tagName" : "tag2",
        "tagValue" : "value2",
        "categories" : ["Category-1", "Category-2"],
        "otherField1" : [],
        "otherField2" : "something-else-2"
    },
    {
        "_id" : ObjectId("6555c652c2d9de74abb09df2"),
        "tagName" : "tag3",
        "tagValue" : "value3",
        "categories" : ["Category-2", "Category-3"],
        "otherField1" : [],
        "otherField2" : "something-else-3"
    }
]

目标结构

[
    {
        "category" : "Category-1",
        "tags" : [
            {"name" : "tag1", "value" : "value1"},
            {"name" : "tag2", "value" : "value2"}
        ]
    },
    {
        "category" : "Category-2",
        "tags" : [
            {"name" : "tag2", "value" : "value2"},
            {"name" : "tag3", "value" : "value3"}
        ]
    },
    {
        "category" : "Category-3",
        "tags" : [{"name" : "tag3", "value" : "value3"}]
    }
]

MongoDB 聚合查询

通过以下聚合管道可实现结构转换,核心是先展开分类数组,再按分类分组收集标签:

db.collection.aggregate([
    // 展开categories数组,每个分类生成一条独立文档
    { $unwind: "$categories" },
    // 按分类分组,收集对应标签
    {
        $group: {
            _id: "$categories",
            tags: {
                $push: {
                    name: "$tagName",
                    value: "$tagValue"
                }
            }
        }
    },
    // 重命名_id为category,并移除原_id字段
    {
        $project: {
            _id: 0,
            category: "$_id",
            tags: 1
        }
    }
])

C#/.NET 7 驱动实现代码

定义数据实体类

// 原始文档实体
public class TagDocument
{
    public ObjectId Id { get; set; }
    public string TagName { get; set; }
    public string TagValue { get; set; }
    public List<string> Categories { get; set; }
    public List<object> OtherField1 { get; set; }
    public string OtherField2 { get; set; }
}

// 聚合结果实体
public class CategoryTagGroup
{
    public string Category { get; set; }
    public List<TagItem> Tags { get; set; }
}

public class TagItem
{
    public string Name { get; set; }
    public string Value { get; set; }
}

聚合查询代码(两种实现方式)

方式一:基于BsonDocument构建管道

using MongoDB.Bson;
using MongoDB.Driver;
using System.Collections.Generic;
using System.Threading.Tasks;

public async Task<List<CategoryTagGroup>> GetCategoryTagsAsync(IMongoCollection<TagDocument> collection)
{
    var pipeline = new BsonDocument[]
    {
        new BsonDocument("$unwind", "$Categories"),
        new BsonDocument("$group", new BsonDocument
        {
            ["_id"] = "$Categories",
            ["tags"] = new BsonDocument("$push", new BsonDocument
            {
                ["name"] = "$TagName",
                ["value"] = "$TagValue"
            })
        }),
        new BsonDocument("$project", new BsonDocument
        {
            ["_id"] = 0,
            ["category"] = "$_id",
            ["tags"] = 1
        })
    };

    return await collection.Aggregate<CategoryTagGroup>(pipeline).ToListAsync();
}

方式二:强类型聚合构建器(更易读)

using MongoDB.Driver;
using System.Collections.Generic;
using System.Threading.Tasks;

public async Task<List<CategoryTagGroup>> GetCategoryTagsStronglyTypedAsync(IMongoCollection<TagDocument> collection)
{
    var aggregation = collection.Aggregate()
        .Unwind(doc => doc.Categories)
        .Group(
            doc => doc.Categories,
            g => new CategoryTagGroup
            {
                Category = g.Key,
                Tags = g.Select(tagDoc => new TagItem
                {
                    Name = tagDoc.TagName,
                    Value = tagDoc.TagValue
                }).ToList()
            }
        );

    return await aggregation.ToListAsync();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 00:27:03