简体   繁体   English

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

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

I'm trying to update a sub-document of a sub-array, but I can't count on the element's position in the array to always be the same, so how do I update it. 我正在尝试更新子数组的子文档,但是我不能指望元素在数组中的位置始终保持相同,因此如何更新它。

For example, here's my document, I just want to push another tag object (key/val) onto the tags array of real_pagenum : 1 of the pdf with the _id of ObjectId("50634e26dc7c22c64d00000a") 例如,这是我的文档,我只想将另一个标签对象(键/值)推到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
        }
    ],
}

To reiterate, the goal is to first target the right pdf by _id , then the right page by real_pagenum and push into that pdf's page's tags array. 重申一下,目标是首先通过_id定位正确的pdf,然后通过real_pagenum正确的页面,并将其推入该pdf页面的tags数组。

I had tried: 我试过了:

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

but that doesn't get to the level I need. 但这达不到我需要的水平。 I've read that I can use a combination of the positional operator with actual element position , but again, I can't guarantee or know the element's position. 我已经读过我可以将位置运算符与实际元素position结合使用,但是同样,我不能保证或知道元素的位置。

This is currently not possible. 目前这是不可能的。 You can only address the highest level array in your document tree with the positional operator. 您只能使用位置运算符寻址文档树中的最高级别的数组。 Any deeper arrays can only be accessed if you know the exact element position. 如果您知道确切的元素位置,则只能访问任何更深的数组。

This is currently an open issue : https://jira.mongodb.org/browse/SERVER-831 当前这是一个未解决的问题: https : //jira.mongodb.org/browse/SERVER-831

It is a currently filed bug in mongodb that the positional operator cannot be used for nested arrays: mongodb中当前存在的一个错误是位置运算符不能用于嵌套数组:

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

The positional operator also cannot be used multiple times in one query, for the time being. 暂时不能在一个查询中多次使用位置运算符。

The best way to handle this in your case may be to change your schema. 解决您的情况的最佳方法可能是更改架构。 In general, having arrays within a document that will grow to an arbitrary size is not a good idea, since BSON documents have a maximum size of 16mb. 通常,在文档中具有将增长为任意大小的数组不是一个好主意,因为BSON文档的最大大小为16mb。

Especially since in this case it seems like your document is basically just an array of pdfs. 特别是因为在这种情况下,您的文档似乎基本上只是pdf数组。 Have you considered creating a separate collection for pdfs? 您是否考虑过为pdf创建单独的集合?

The other answers are correct as far as doing an atomic update of the document. 至于对文档进行原子更新,其他答案是正确的。

I highly agree that this looks like less than optimal schema - a document per pdf might make more sense then you only have an array of pages within each document which you can update atomically with positional operator. 我非常同意这看起来似乎不是最佳方案-每个pdf文档可能更有意义,然后每个文档中只有一个页面数组,您可以使用位置运算符自动更新页面。

If you cannot modify the schema, you can still make the update you want, it may not be thread safe though. 如果您无法修改架构,则仍然可以进行所需的更新,尽管它可能不是线程安全的。 You can read the entire document into your application, modify appropriate fields in code and then save the item. 您可以将整个文档读入应用程序,在代码中修改适当的字段,然后保存该项目。 If you wanted to make sure that multiple threads wouldn't stomp over each other, you would have to keep a version in each document and increment it on each "update" which would be conditional on the version not having been changed in the mean time. 如果您要确保多个线程不会相互重叠,则必须在每个文档中保留一个版本,并在每次“更新”时对其进行递增,这要以同时未更改该版本为条件。 It's more complex and it still requires an additional field in the current schema, but at least it allows you to do what you state you need to do. 它更复杂,并且在当前模式中仍然需要一个附加字段,但是至少它允许您执行需要执行的操作。

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

相关问题 MongoDB:使用索引更新数组中的子文档 - MongoDB: Update a sub-document in an array using an index 从MongoDB中的子文档数组中查找/获取子数组 - find/get sub-array from an array of sub-document in MongoDB 在 MongoDB 文档中,使用 Node JS,如何找到数组中的最后一项,并将文档插入到该项的子数组中? - In a MongoDB document, using Node JS, how do I find the last item in an array, and insert a document into said item's sub-array? 如何将现有的子文档推送到 MongoDB 中的嵌入式数组中? - How to push an existing sub-document into an embedded array in MongoDB? mongodb更新或插入子数组 - mongodb update or insert sub-array 如何在mongo中更新文档子数组中的字段 - How to update field in document sub-array in mongo 如何将此数组分解为类似字母类型的子数组(在连续位置) - How do I break this array into sub-array(at continuous position) of similar type of alphabets 返回Mongodb子文档中的一组数据 - Return one array of data in sub-document of Mongodb MongoDB:从子数组为空的元素中删除子数组 - MongoDB: Remove Sub-Array from Element where The Sub-Array is Empty 更改子阵列何时更新子阵列与创建新子阵列? [JavaScript] - When does changing a sub-array update the sub-array vs. creating a new sub-array? [JavaScript]
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM