【问题标题】:Adding a new element to a nested document向嵌套文档中添加新元素
【发布时间】:2016-08-05 04:49:41
【问题描述】:

我正在尝试向嵌套的“消息”文档添加一条新消息(键为“3”),但 $addToSet 或 $push 不起作用。是否可以将新的消息元素推送到这样的结构?一开始,messages 属性是一个数组,但我的 mongodb 提供程序将数组转换为这样的结构。仅供参考:我正在通过 node.js 和 mongojs 访问 mongodb,但本地 mongodb 解决方案也将是完美的。

{
    "messages" : 
    {
        "0" : 
        {
            "foo": "bar0"  
        },
        "1" : 
        {
            "foo": "bar1"  
        },
        "2" : 
        {
            "foo": "bar2"   
        },
    },
    "name" : "MyName"   
}

【问题讨论】:

  • $addToSet$push 仅适用于数组(包含在 [] 中)。在您的文档中,messages 是一个对象而不是一个数组。因此,您必须使用 update 语句:db.collection.update({}, {$set:{"messages.3":{"foo":"bar3"}}})
  • 我想到了类似的东西,但我必须先获取消息文档的计数,对吧?
  • 这就是为什么你应该使用数组来代替。
  • 确实,当我通过提供者的编辑器添加文档时,它会将数组转换为这样的文档:/
  • 嗯,我正在使用 MongoSoup 的那个。它是德国的 mongodb 提供者。

标签: node.js mongodb mongojs


【解决方案1】:

问题在于 MongoSoup 的编辑器会自动将数组转换为文档集合。当我通过命令行或我的 node.js 应用程序创建数组时,一切都像我预期的那样。

还是谢谢你……我的错!

【讨论】:

    【解决方案2】:

    基本上你只是想添加一个子文档,所以只需$setting 该文档就可以了:

    db.bar.update({_id : ObjectId("542194f8b32cda36885e1d9e") }, 
                  {$set : {"messages.3" : {"foo" : "bar3"}}})
    

    您需要根据您的真实文档的外观替换一个适当的匹配标准,而不是我使用的 _id。添加/更新示例文档的完整过程如下:

    > foo = {
        "messages" : {
            "0" : {
                "foo" : "bar0"
            },
            "1" : {
                "foo" : "bar1"
            },
            "2" : {
                "foo" : "bar2"
            }
        },
        "name" : "MyName"
    }
    
    > db.bar.insert(foo)
    WriteResult({ "nInserted" : 1 })
    
    > db.bar.findOne()
    {
        "_id" : ObjectId("542194f8b32cda36885e1d9e"),
        "messages" : {
            "0" : {
                "foo" : "bar0"
            },
            "1" : {
                "foo" : "bar1"
            },
            "2" : {
                "foo" : "bar2"
            }
        },
        "name" : "MyName"
    }
    
    > db.bar.update({_id : ObjectId("542194f8b32cda36885e1d9e") }, {$set : {"messages.3" : {"foo" : "bar3"}}})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    
    > db.bar.findOne()
    {
        "_id" : ObjectId("542194f8b32cda36885e1d9e"),
        "messages" : {
            "0" : {
                "foo" : "bar0"
            },
            "1" : {
                "foo" : "bar1"
            },
            "2" : {
                "foo" : "bar2"
            },
            "3" : {
                "foo" : "bar3"
            }
        },
        "name" : "MyName"
    }
    

    明显的限制是这将覆盖任何现有的messages.3 字段(如果它已经存在),因此您需要小心并且还需要跟踪该字段中的最新消息。

    【讨论】:

    • OP 不会以这种方式存储文档。它存储为一个数组。
    • 这实际上不是问题所说的,实际上标题明确表示它是嵌套文档而不是数组,这就是 $push 运算符不起作用的原因
    • 我想,标题有误导性,请阅读描述和cmets。
    • “一开始消息属性是一个数组,但我的 mongodb 提供程序将数组转换为这样的结构”,“当我通过我的提供程序的编辑器添加文档时确实 buuuuut 然后它将数组转换为这样的一个文件:/”,并且标题似乎令人困惑。在这种情况下,我认为答案是不正确的。
    • 对,所以文档不是数组,它一个嵌套文档,我使用了给出的文档示例。如果您所说的是正确的,那么问题的每个部分都是不正确的——标题、描述和示例文档。我已经按要求回答了这个问题,您似乎希望我回答一些实际上从未被问过的问题,而您从中推断出......无处 - 这对我来说毫无意义
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 2015-04-03
    相关资源
    最近更新 更多