MongoDB查询转换文档

MongoDB query to transform documents

提问人:Bhanu 提问时间:11/16/2023 最后编辑:Yong ShunBhanu 更新时间:11/16/2023 访问量:28

问:

我在 MongoDB 6.0 中构建了如下文档:

[
    {
        "_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"
            }
        ]
    }
]

我使用了 and 运算符,但无法获得最终结果。 任何帮助都是值得赞赏的。$unwind$group

PS:最后,我必须使用C#/.NET 7驱动程序翻译MongoDB查询。

数组 mongodb-query 聚合框架 mongodb-.net驱动程序

评论


答:

2赞 Yong Shun 11/16/2023 #1

是的,您的查询应包含 和 stages。$unwind$group

db.collection.aggregate([
  {
    $unwind: "$categories"
  },
  {
    $group: {
      _id: "$categories",
      tags: {
        $push: {
          name: "$tagName",
          value: "$tagValue"
        }
      }
    }
  },
  {
    $project: {
      _id: 0,
      category: "$_id",
      tags: 1
    }
  }
])

对于 MongoDB .NET 驱动程序语法,应为展开和投影/结果创建模型。

例:

public class RootModel
{
    public ObjectId Id { get; set; }
    public string TagName { get; set; }
    public string TagValue { get; set; }
    public List<string> Categories { get; set; }
    public List<string> OtherField1 { get; set; }
    public string OtherField2 { get; set; }
}

public class UnwindRootModel
{
    public ObjectId Id { get; set; }
    public string TagName { get; set; }
    public string TagValue { get; set; }
    public string Categories { get; set; }
    public List<string> OtherField1 { get; set; }
    public string OtherField2 { get; set; }
}

[BsonNoId]
public class ResultModel
{
    public string Category { get; set; }
    public List<TagModel> Tags { get;set; }
}

[BsonNoId]
public class TagModel
{
    public string Name { get; set; }
    public string Value { get; set; }
}

在从集合中查询之前,由于文档的字段采用驼峰大小写,因此您需要通过属性将字段名称指定为类属性的驼峰大小写,或者您应该注册驼峰案例包。[BsonElement]

var pack = new ConventionPack();
pack.Add(new CamelCaseElementNameConvention());
ConventionRegistry.Register("camel case", pack, t => true);

使用 Aggregate Fluent:

var result = await _collection.Aggregate()
    .Unwind<RootModel, UnwindRootModel>(x => x.Categories)
    .Group(x => x.Categories,
        g => new ResultModel
        {
            Category = g.Key,
            Tags = g.Select(y => new TagModel
            {
                Name = y.TagName,
                Value = y.TagValue
            }).Distinct().ToList()
        })
    .ToListAsync();

enter image description here

如果您在编写 Aggregate Fluent 查询时遇到困难,可以使用 MongoDB Compass 提供原始查询。

更新:正如帖子所有者所提到的,要删除重复的标记,请应用于 Aggregate Fluent/LINQ 中的列表。.Distinct()Tags

评论

1赞 Bhanu 11/16/2023
我使用 $addToSet 而不是 $push 来消除重复的标签。谢谢。
0赞 Yong Shun 11/16/2023
是的,好吧,在这种情况下,您应该使用来消除重复项。.Distinct()