繁体   English   中英

使用MongoDB,当元素位置未知时,如何更新子数组的子文档?

[英]Using MongoDB, how do I update a sub-document of a sub-array when element position is unknown?

我正在尝试更新子数组的子文档,但是我不能指望元素在数组中的位置始终保持相同,因此如何更新它。

例如,这是我的文档,我只想将另一个标签对象(键/值)推到real_pagenumtags数组上:pdf的_idObjectId("50634e26dc7c22c64d00000a")

{
    "_id" : ObjectId("503b83dfad79cc8d26000004"),
    "pdfs" : [
        {
            "_id" : ObjectId("50634e26dc7c22c64d00000a"),
            "pages" : [
                {
                    "real_pagenum" : 1,
                    "_id" : ObjectId("50634e74dc7c22c64d00002b"),
                    "tags" : [
                        {
                            "key" : "Item",
                            "val" : "foo"
                        },
                        {
                            "key" : "Item",
                            "val" : "bar"
                        }

                    ]

                },
                {
                    "real_pagenum" : 2,
                    "_id" : ObjectId("50634e74dc7c22c64d00002b")
                }
            ],
            "title" : "PDF3",
            "version" : 3
        }
    ],
}

重申一下,目标是首先通过_id定位正确的pdf,然后通过real_pagenum正确的页面,并将其推入该pdf页面的tags数组。

我试过了:

db.projects.update({'pdfs.pdf_id':ObjectId("50634e25dc7c22c64d000007")},
    {$push:{'pages.$.tags':{'key':'foo','val':'bar'}}},false,false);

但这达不到我需要的水平。 我已经读过我可以将位置运算符与实际元素position结合使用,但是同样,我不能保证或知道元素的位置。

目前这是不可能的。 您只能使用位置运算符寻址文档树中的最高级别的数组。 如果您知道确切的元素位置,则只能访问任何更深的数组。

当前这是一个未解决的问题: https : //jira.mongodb.org/browse/SERVER-831

mongodb中当前存在的一个错误是位置运算符不能用于嵌套数组:

https://jira.mongodb.org/browse/SERVER-831

暂时不能在一个查询中多次使用位置运算符。

解决您的情况的最佳方法可能是更改架构。 通常,在文档中具有将增长为任意大小的数组不是一个好主意,因为BSON文档的最大大小为16mb。

特别是因为在这种情况下,您的文档似乎基本上只是pdf数组。 您是否考虑过为pdf创建单独的集合?

至于对文档进行原子更新,其他答案是正确的。

我非常同意这看起来似乎不是最佳方案-每个pdf文档可能更有意义,然后每个文档中只有一个页面数组,您可以使用位置运算符自动更新页面。

如果您无法修改架构,则仍然可以进行所需的更新,尽管它可能不是线程安全的。 您可以将整个文档读入应用程序,在代码中修改适当的字段,然后保存该项目。 如果您要确保多个线程不会相互重叠,则必须在每个文档中保留一个版本,并在每次“更新”时对其进行递增,这要以同时未更改该版本为条件。 它更复杂,并且在当前模式中仍然需要一个附加字段,但是至少它允许您执行需要执行的操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM