C# MongoDB - 如何向多个嵌套数组元素添加和删除项?

4

我有一个在MongoDB中的文档,看起来像这样:

{
    "Id":"123",
    "Product": "test",
    "Tags":[
        {
            "Name": "name",
            "Categories": [
                {
                    //item
                },
                {
                    //item
                }
            ]
        },
        {
            "Name": "name",
            "Categories": [
                {
                    //item
                },
                {
                    //item
                }
            ]
        }
    ]
}

现在,我需要添加一个新的Item,并且它需要被添加到该Product的所有Tags元素的类别中,使用它的Id。 例如,当我插入Item 3时,文档应该是这样的:
{
    "Id":"123",
    "Product": "test",
    "Tags":[
        {
            "Name": "name",
            "Categories": [
                {
                    //item 1
                },
                {
                    //item 2
                },
                {
                    //item 3
                }
            ]
        },
        {
            "Name": "name",
            "Categories": [
                {
                    //item 1
                },
                {
                    //item 2
                },
                {
                    //item 3
                }
            ]
        }
    ]
}

同样地,如果要删除一个项目,也需要从所有类别中删除。是否有一种方法可以使用C# MongoDB Driver在不拉取对象并“手动”更新它们的情况下完成此操作?

1个回答

11
您可以在2.5驱动程序和3.6版本中尝试以下操作。使用UpdateOne方法,找到符合filter条件的文档并进行更新,其中包括新的定位标识符以更新数组中的多个元素。使用$[]可更新所有Tags数组,以包含所有Categories数组中的新项目。它作为更新数组中所有元素的占位符。使用Push。请注意保留HTML标签。
var filter = Builders<Product>.Filter.Eq("Id", "123");
var update = Builders<Product>.Update.Push("Tags.$[].Categories", "Item 3");
var result = collection.UpdateOne(filter, update);

拉取
var filter = Builders<Product>.Filter.Eq("Id", "123");
var update = Builders<Product>.Update.Pull("Tags.$[].Categories", "Item 3");
var result = collection.UpdateOne(filter, update);

额外信息:

您可以在UpdateOptions中设置ArrayFilters选项,以应用查询条件到嵌套数组,控制要更新的元素。

例如,要更新所有标签数组中类别为Name名称的标签。

var filter = Builders<Product>.Filter.Eq("Id", "123");
var update = Builders<Product>.Update.Push("Tags.$[t].Categories", "Item 3");
var arrayFilters = new List<ArrayFilterDefinition>{ new ArrayFilterDefinition(new BsonDocument("t.Name", "name")) };
var updateOptions = new UpdateOptions({ArrayFilters = arrayFilters});
var result = collection.UpdateOne(filter, update, updateOptions);

我在Push解决方案上遇到了这个错误:“写操作导致错误。\r\n无法使用部分(Tags of Tags.$[].Categories)来遍历元素。 - Liran Friedman
看起来你没有使用最新的3.6版本。在shell中执行db.version()以检查版本。 - s7vr
你有没有弄清楚这里的问题? - s7vr
是的。结果证明这是一个mongo db设置问题,您需要运行此命令db.adminCommand( { setFeatureCompatibilityVersion: "3.6" } )才能使用新的数组过滤器... - Liran Friedman
我想说的是,这个 答案 最终给了我正确的结果! - Jose A
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接