使用多个嵌套文档更新文档字段

时间:2020-01-09 20:57:54

标签: mongodb mongodb-query nested-documents

我有一个现有的MongoDB文档,其中包含字段files(以及其他字段)。 files字段是一个对象,现在我想用几个嵌套文档更新此字段。我已成功使用以下语法插入一个嵌套文档:

db.collection.updateOne(
    { "id": 1 },
    {
        $set: {
            "files":
            {
                "filename1": {
                    "a": "Lorem ipsum dolor",
                    "b": "Sit amet consectetur",
                    "c": "Adipiscing elit"
                }
            }
        }
    })

接下来,我尝试同时在失败的file字段中再插入2个文档

db.collection.updateOne(
    { "id": 1 },
    {
        $set: {
            "files":
            {
                "filename2": {
                    "d": "Lorem ipsum dolor",
                    "e": "Sit amet consectetur",
                    "f": "Adipiscing elit"
                }
            }
{
        "filename3": {
            "g": "Duis aute irure",
            "h": "Labore et dolore",
            "i": "Eiusmod tempor incididunt"
        }
    }
}})

此操作无效后,我尝试使用第一个代码块一个接一个地插入记录,但插入filename2(我不想覆盖现有的filename1)。该文档已插入files对象中,但覆盖了现有文档filename1。我尝试了几种不同的变体,但没有任何效果。

有关如何在字段中嵌套多个文档的任何反馈/帮助都将很有帮助。

1 个答案:

答案 0 :(得分:0)

它不起作用,因为您的更新查询没有问题,请检查此:

db.collection.updateOne(
    { "id": 1 },
    {
        $set: {
            "files":
            {
                "filename2": {
                    "d": "Lorem ipsum dolor",
                    "e": "Sit amet consectetur",
                    "f": "Adipiscing elit"
                },
                "filename3": {
                    "g": "Duis aute irure",
                    "h": "Labore et dolore",
                    "i": "Eiusmod tempor incididunt"
                }
            }
        }
    })

上面的查询可以工作,但是这里有一个问题-因为您正在使用files,它将用发送的新files替换现有的$set字段,而files会替换现有的字段具有新值的字段(如果旧值与新值不同)。

如果$push是一个数组,则可以使用$addToSetfiles向现有$set字段中添加新值(然后,只需将files替换为其中一种将起作用),但是如果您想将.作为对象,则需要读取它并使用代码中的files表示法注入新值并编写整个{{1} }使用$set返回MongoDB,这是对DB的两次调用。换句话说,您可以通过以下方式在一个数据库调用中完成此操作:

db.updateObject.updateOne({"id": 1}, {
    $set: {
       /** Same like programming language you use `.`,
           You're not replacing files rather you're adding new objects to files,
           If 'files.filename2' already exists in DB then it would be updated. */
        'files.filename2': {
            "d": "Lorem ipsum dolor",
            "e": "Sit amet consectetur",
            "f": "Adipiscing elit"
        }, 'files.filename3': {
            "g": "Duis aute irure",
            "h": "Labore et dolore",
            "i": "Eiusmod tempor incididunt"
        }
    }
})

其中将使用两个新对象更新files对象:

/* 1 */
{
    "_id" : ObjectId("5e179dac627ef7823643cd97"),
    "id" : 1,
    "files" : {
        "filename1" : {
            "a" : "Lorem ipsum dolor",
            "b" : "Sit amet consectetur",
            "c" : "Adipiscing elit"
        },
        "filename2" : {
            "d" : "Lorem ipsum dolor",
            "e" : "Sit amet consectetur",
            "f" : "Adipiscing elit"
        },
        "filename3" : {
            "g" : "Duis aute irure",
            "h" : "Labore et dolore",
            "i" : "Eiusmod tempor incididunt"
        }
    }
}