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

时间:2012-09-27 14:19:20

标签: arrays mongodb

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

例如,这是我的文档,我只是想将另一个标记对象(key / val)推送到tags的{​​{1}}数组{1}}:pdf的real_pagenum _id

ObjectId("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 } ], } 定位正确的pdf,然后按_id定位正确的页面,然后推送到该pdf页面的real_pagenum数组。

我曾尝试过:

tags

但这没有达到我需要的水平。我读过我可以使用combination of the positional operator with actual element position,但我再也不能保证或知道该元素的位置。

3 个答案:

答案 0 :(得分:1)

目前无法做到这一点。您只能使用位置运算符来处理文档树中的最高级别数组。只有知道确切的元素位置,才能访问任何更深的数组。

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

答案 1 :(得分:0)

mongodb中当前提交的错误是位置运算符不能用于嵌套数组:

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

目前,位置运算符也不能在一个查询中多次使用。

在您的情况下处理此问题的最佳方法可能是更改您的架构。通常,将文档中的数组增长到任意大小并不是一个好主意,因为BSON文档的最大大小为16mb。

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

答案 2 :(得分:0)

就文档的原子更新而言,其他答案是正确的。

我非常同意这看起来不是最优的架构 - 每个pdf文档可能更有意义,因此每个文档中只有一个页面数组,您可以使用位置操作符进行原子更新。

如果您无法修改架构,您仍然可以进行所需的更新,但它可能不是线程安全的。您可以将整个文档读入您的应用程序,修改代码中的相应字段,然后保存该项目。如果你想确保多个线程不会互相攻击,你必须在每个文档中保留一个版本并在每个“更新”上增加它,这将取决于同时没有更改的版本。它更复杂,它仍然需要当前架构中的一个额外字段,但至少它允许你做你所说的你需要做的事情。