【问题标题】:Update a document field with multiple nested documents使用多个嵌套文档更新文档字段
【发布时间】:2020-01-10 05:49:40
【问题描述】:

我有一个现有的 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。我尝试了几种不同的变体,但没有任何效果。

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

【问题讨论】:

  • 您的第二个查询有语法问题,请查看下面的答案。

标签: mongodb mongodb-query nested-documents


【解决方案1】:

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

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 或 $addToSet 向现有的 files 字段添加新值(然后您只需将 $set 替换为其中之一即可),但如果您希望将files 作为一个对象,或者您需要读取它并在代码中使用. 符号注入新值,然后使用$set 将整个files 写回MongoDB,这是对DB 的两次调用。在另一种方式中,您可以通过以下方式在一个 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"
        }
    }
}

【讨论】:

  • 完美运行,感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2017-06-09
  • 2018-03-30
  • 2022-01-02
  • 2018-04-07
  • 1970-01-01
  • 2016-08-04
  • 2019-05-11
  • 2012-07-30
相关资源
最近更新 更多