【问题标题】:Updated nested subdocuments in MongoDB更新了 MongoDB 中的嵌套子文档
【发布时间】:2014-09-23 08:44:15
【问题描述】:

我正在尝试更新 mongodb 中的嵌套子文档,

  {
id: 100, 
     status: [ { 

                 campaigns: [ 
                    { timestamp: "2014-07-30", 
                      task: [
                                { 
                                  id: "1",
                                  created: "2014-07-30"
                                } 

                        ]
                    }, 
                    { timestamp: "2014-07-31", 
                      task: [
                                { 
                                  id: "2",
                                  created: "2014-07-31" // need to update this field
                                } 

                        ]
                    }, 
                ]
            }, 
        ]

    }

更新查询

db.collectionname.update({"id": 100,"status.campaigns.task.id":"2"},{$set:{"status.0.campaigns.$.task.created:"2014-08-01"}});

上面的查询只更新第一条记录(task.id = "1" 创建日期)它不更新 task.id="2" 子文档!!!!

【问题讨论】:

  • 你为什么使用status.0?是否只需要更新status 数组中的第一个条目?
  • campaings 位置参数而不是状态数组中的问题
  • 可以根据需要更新任务,但您需要知道它在数组中的位置。你事先知道吗?

标签: mongodb subdocument


【解决方案1】:

可以更新子文档,但您需要知道它在文档结构中的各种嵌套数组中的位置。如果您对插入嵌套数组的子文档的 id 字段遵循特定编号方案,则可能会出现这种情况。

如果这对您来说是一个可行的策略,那么您的 update() 将不需要第一个参数中的第二个键/值对,因为您只是在查找包含要更新的子文档和 @987654324 的文档@ 字段是唯一的。对于第二个参数,您将使用您将拥有的索引作为嵌套数组中子文档的位置。

对于您发布的示例文档,您正在更新 @ 的 second 元素中 task 数组的 first 元素中的 created 字段987654327@ 数组在status 数组的first 元素中,然后你做如下操作:

db.collection.update({ "_id": 100}, { $set: { "status.0.campaigns.1.task.0.created" : "2014-08-01" }});

但是,如果您不知道要更新的子文档的位置,那么您将无法更新它。这是因为,正如documentation 中所解释的那样,“位置运算符不能用于遍历多个数组的查询”。

【讨论】:

    【解决方案2】:

    嵌套数组 位置 $ 运算符不能用于遍历多个数组的查询,例如遍历嵌套在其他数组中的数组的查询,因为 $ 占位符的替换是单个值

    查看mongoDB docs on positional operator

    那么你有没有三个嵌套数组status,campaigns,task。位置运算符将不起作用。

    我的猜测是最里面的位置(最里面的数组)存储在$ 中。这就是为什么您将$ 设为0

    如果您对此问题感兴趣,请关注JIRA trackable并投票。

    【讨论】:

    • 对于您当前的架构,您无法在单个更新查询中执行此操作。重新考虑您的架构可能会有所帮助。这是一个已知问题和一个JIRA Trackable
    • 我需要在 php 的 yiimongoDBsuite 中执行此操作
    • 没关系。 MongoDB 不支持嵌套数组的位置运算符。您应该考虑更改架构。
    • 你能为上面的例子推荐任何架构设计吗?
    • 没那么简单。你需要考虑很多因素,比如查询、读取频率、写入频率等等来设计一个好的模式。 This site 更适合这样的东西
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-12
    • 2016-08-04
    • 2010-11-11
    • 2021-03-26
    • 2018-04-23
    • 2016-11-23
    相关资源
    最近更新 更多