首页 > 解决方案 > 如何从 MongoDb 中删除这些嵌入的文档?

问题描述

我有一个字段是嵌入式文档的字典(我希望我的术语是正确的)。我正在尝试删除键为 NOT 的所有嵌入文档(从此字典中)abc

这个 mongo 脚本效果很好:

db.getCollection("users").update(
    {},
    {
        $unset: 
        { 
            "prefs.state.AAAA": "",
            "prefs.state.BBBB": "",
            "prefs.state.CCCC": "",
        } 
    },
    {
        multi: true
    }
);

我的问题是我实际上不知道这个字典列表中所有可能的键。

在上面的例子中,我有

但我可以多吃一大堆。

这是一个示例合法文件:

{ 
    "_id" : 1.0, 
    "prefs" : {
        "state" : {
            "abc123" : { // TO STAY
                "name" : "name1", 
                "age" : 1.0
            }, 
            "AAAA" : { // TO BE REMOVED
                "name" : "name2", 
                "age" : 2.0
            }, 
            "XASDASD" : { // TO BE REMOVED
                "name" : "name3", 
                "age" : 3.0
            }
        }
    }
}
{ 
    "_id" : 2.0, 
    "prefs" : {
        "state" : {} // NO DATA, but this is OK
    }
}
{ 
    "_id" : 3.0, 
    "prefs" : {
        "state" : {
            "CCCC" : { // TO BE REMOVED
                "name" : "name4", 
                "age" : 4.0
            }
        }
    }
}

所以我想做的是:

如果prefs.state.<KEY>不等于abc123,那么这个嵌入的文档应该被删除。

因此,鉴于上面的 mongo 脚本,它会找到prefs.state.AAAA并取消设置该字段,这基本上会破坏嵌入的文档。

这可能吗?


更新 1:这是 shell 输出(显示失败)。我在应用程序“Studio 3T”中运行了这个

脚本:

db = db.getSiblingDB("users");


db.getCollection("jussytest").updateMany(
    {},
    [
        {
            $set: {
                "prefs.state": {
                    $arrayToObject: {
                        $filter: {
                            input: { $objectToArray: "$prefs.state" },
                            as: "x",
                            cond: { $eq: ["$$x.k", "abc123"] }
                        }
                    }
                }
            }
        }
    ]);
    
 db.getCollection("jussytest").find({});
    

结果:

MongoDB shell version v4.0.16
connecting to: mongodb://localhost:27017/users
Implicit session: session { "id" : UUID("1ae46c5b-a711-4f56-adb4-5e5f8a093750") }
MongoDB server version: 4.4.3
WARNING: shell and server versions do not match
users
authenticated
users
2021-03-10T09:17:43.659+1100 E QUERY    [js] Error: the update operation document must contain atomic operators :

DBCollection.prototype.updateMany@src/mongo/shell/crud_api.js:625:1

@(shell):1:1

The find query will be run with Query Assist.

标签: mongodb

解决方案


试试这个更新管道(确保不要尝试生产数据):

db.users.updateMany(
    {},
    [
        {
            $set: {
                "prefs.state": {
                    $arrayToObject: {
                        $filter: {
                            input: { $objectToArray: "$prefs.state" },
                            as: "x",
                            cond: { $eq: ["$$x.k", "abc123"] }
                        }
                    }
                }
            }
        }
    ])

推荐阅读