【问题标题】:Howto MongoDB update / $set entire subdocumentHowto MongoDB更新/$设置整个子文档
【发布时间】:2023-03-30 14:27:02
【问题描述】:

在我的 MongoDB 中,我有 Document1,如下所示。我想进入“main.accounts”(以及后来的“main.entries”)文档,并更新($set)“content”数组中的整个子文档。Wrt 子文档,到目前为止,我'已经能够在“内容”子数组中添加和删除文档。但在这种情况下,我想更新整个文档;而不仅仅是更新($set)匹配文档中的一个属性。

下面,我尝试只使用一个$set,一个带有$elemMatch 的$set。而且我也尝试过 findAndModify,但无济于事。当然,我已经 i) RTFM,环顾四周 ii) 互联网和 iii) SO,以找到解决方案。有没有人能够以这种方式更新整个文档?

谢谢 蒂姆

更新尝试 1 - 这是唯一有效的更新,但会将整个 "content" 数组设置为哈希 ... { "fu" : "bar" }

db.bookkeeping.update( { 所有者:“twashing@gmail.com”, “content.content.tag”:“帐户”, “content.content.id”:“一个” }, { $set : { "content.$.content" : { "fu" : "bar" } } } )

更新尝试 2 - 这不会失败,但不会更新相关文档

db.bookkeeping.update( { 所有者:“fu”, 事情:{$elemMatch:{“content.content.tag”:“帐户”,“content.content.id”:“one”}} }, { $set : { "thing" : { "fu" : "bar" } } } )

更新尝试 3 - 这不会失败,但不会更新相关文档

db.bookkeeping.update( {东西:{$elemMatch:{所有者:“fu”,“content.content.tag”:“帐户”,“content.content.id”:“one”}}}, { $set : { "thing.content.content.$" : { "fu" : "bar" } } } )

文档1

{ “_id”:“fid”, “内容” : [ { “内容” : [ { “id”:“一个”, “标签”:“帐户” }, { “id”:“两个”, “标签”:“帐户” }, { “id”:“三个”, “标签”:“帐户” }, { “id”:“四个”, “标签”:“帐户” }, { “id”:“五”, “标签”:“帐户” } ], “id”:“main.accounts”, “标签”:“帐户” }, { “标签”:“期刊”, “id”:“main.journals”, “内容” : [ { “标签”:“期刊”, “id”:“总账”, “名称”:“总账”, “类型” : ””, “平衡” : ””, “内容” : [ { “标签”:“条目”, “id”:“main.entries”, “内容” : [ ] } ] } ] } ], “所有者”:“福”, “标签”:“富巴” }

【问题讨论】:

  • 您要更新哪个文档。被这个问题弄糊涂了。为什么你一直在谈论更新($set)?
  • 我正在尝试更新对象:{ "id" : "one", "tag" : "account" }。我的意思是,从功能上讲,我想更新所述文档。我正在尝试使用 $set 运算符来做到这一点。 Hth.

标签: mongodb database nosql


【解决方案1】:

您将无法使用位置运算符$ 更新第二级数组。(数组内的数组)

This link 可能会帮助你

【讨论】:

  • 嘿 Ravi,感谢您对 $ 位置运算符的见解。但是在更新值时,该链接仅显示更新哈希的单个成员,例如 ... name : "Smells Like Teen Spirit!!"。我无法更新整个文档,例如 { name : "Smells Like Teen Spirit!!", order : 1, duration : 301 }。我可以用 $set 做到这一点吗?谢谢。
  • 好的,我通过在查询和更新路径中硬编码数组位置来解决这个问题。该链接向我提供了解决方案,非常感谢。所以我有类似以下的内容(调用 mongodb 的 Clojure 代码):(mc/update "bookkeeping" { :owner uname "content.1.content.0.content.0.content.tag" "entry" } { mop/$set { :content.1.content.0.content.0.content.$ entry } } )。是我,还是 MongoDB 的更新语义真的令人费解且解释不清?无论如何,谢谢。
【解决方案2】:

我相信如果没有一些编程逻辑,您无法在 mongoDB 控制台中执行此操作,因为您在结构中使用多个数组并且正在搜索子文档 (content[documents]) (main.accounts 和 main.entries ) 在一个数组中,它将返回相同的根文档,但在该返回值中,您无法知道内容数组中的哪个位置是您的标准。因此,您无法在正确的位置注入新值。

如果可能的话,我建议重组文档以避免太多嵌套数组(内容->内容->内容->内容),特别是如果您打算对其中的子集进行一些更新。毕竟这是 NoSQL,所以在你的设计中包含一些冗余数据很好,只要这让你的生活更轻松,你的代码更干净。

【讨论】:

  • 对。所以这个练习教给我的一件事是,NoSQL 可能除了非常扁平的结构外,对其他任何东西都没有好处。看起来它不应该比1级更深。我不接受在任何现代数据服务中,更新文档中任何位置的内容都应该很困难。此外,JQuery Selectors(甚至XQuery)已经解决了很长一段时间。所以不,我不倾向于重组我的文档来满足 MongoDB 的限制。
  • @golja 这不是 NoSQL 文档驱动数据结构的重点吗?能够嵌套东西,所以我们不必在整个地方都有收藏?我同意 nutritioustim
猜你喜欢
  • 2021-03-26
  • 1970-01-01
  • 2011-08-04
  • 2016-10-15
  • 1970-01-01
  • 2017-08-15
  • 2014-09-27
  • 1970-01-01
相关资源
最近更新 更多