在 Mongodb 中使用$pull删除深度嵌入的对象

Using $pull in Mongodb to remove a deeply embedded object

本文关键字:深度 对象 删除 pull Mongodb      更新时间:2023-09-26

我正在尝试从嵌入的数组中删除($pull)对象。(使用 javascript/node.js 驱动程序。

下面是示例数据,其中 1、2、3 是级别:

{
    one : "All",
    one : [
        {
        name: "People",
        two: [
            { 
            three_id: 123,
            three: "Jonny",
            },
            { 
            three_id: 456,
            three: "Bobby",
            }
        ]
        },
        {
        name: "Animals",
        two: [
            { 
            three_id: 828,
            three: "Cat",
            },
            { 
            three_id: 282,
            three: "Dog",
            }
        ]
        }
    ]   
}

在这个例子中,我试图摆脱"鲍比"。

如果需要,我可以在"三级"上成功匹配文档,如下所示:

db.test.find({"one.two.three_id" : 456});

但是,我不知道如何使用update消除该记录。以下是一些尝试,这些尝试都不起作用:

// failed attempts
db.test.update({"one.two.three_id" : 456}, {$pull:{'one.$.two.$.three_id': 456}});
db.test.update({"one.two.three_id" : 456}, {$pull:{'three_id': 456}});
// deletes entire level two "People"
db.test.update({"one.two.three_id" : 456}, {$pull: {one: {two : {$elemMatch: {'three_id': 456}}}}});

我读到你不能使用两个位置$ operators,你必须知道第二个位置的索引位置。但是,我想避免使用要删除的嵌入式词典的索引。

参考:蒙戈德拉

http://docs.mongodb.org/manual/reference/operator/update/pull/

$pull对象中的键值必须是目标数组的路径。 这似乎有效:

db.test.update(
    {'one.two.three_id': 456},
    {$pull: {'one.$.two': {three_id: 456}}}
);

在这种情况下,看起来$表示第一个匹配数组级别的索引,因此即使我们在多个嵌套级别之间进行匹配,它也可以正常工作。