如何更新 MongoDB 中的子文档?

Posted

技术标签:

【中文标题】如何更新 MongoDB 中的子文档?【英文标题】:How can I update a subdocument in MongoDB? 【发布时间】:2016-06-17 18:36:49 【问题描述】:

在 Mongoose 中创建的用于更新子文档的代码不起作用。所以我尝试在 Mongo Shell 中更新子文档。 这是文档(位置)和子文档(评论):


"_id" : ObjectId("56d8c73314fbc7e702cfb8c4"),
"name" : "Costly",
"address" : "150, Super Street",
"coords" : [
    -0.9630884,
    51.451041
],
"reviews" : [
    
        "author" : "kyle riggen1",
        "_id" : ObjectId("56d8de74cc7f953efd8455d9"),
        "rating" : 4,
        "timestamp" : ISODate("2015-06-01T06:00:00Z"),
        "reviewText" : "will the ID work?"
    
],
"rating" : 0,
"__v" : 2

以下是我更新子文档的一些尝试:This question gave this format:

update( 
       _id: "56d8c73314fbc7e702cfb8c4", 
       "reviews._id": ObjectId("56d8de74cc7f953efd8455d9")
   ,
       $set: "reviews.$.rating": 1
   , false, true
);

这会返回“未定义更新”的错误,如图所示:

2016-03-03T22:52:44.445-0700 E QUERY    [thread1] ReferenceError: update is not defined :
@(shell):1:1

我认为是因为命令没有以 db.locations.update() 开头

MongoDB documentation used this format:

db.locations.update(
   
     _id: "56d8c73314fbc7e702cfb8c4",
     review:  $elemMatch:  author: "kyle riggen1"  
   ,
    $set:  "location.$.rating" : 1  
)

这会返回一个有效的更新,但更新实际上并未发生,如图所示:

WriteResult( "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 )

This question used this format:

db.locations.update(
    _id: "56d8c73314fbc7e702cfb8c4",
    'review.author': 'kyle riggen1'
  ,
   $set:  'review.$.rating': 1 
)

返回的结果与此处所示的 MongoDB 文档相同:

WriteResult( "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 )

所以我猜这些查询是有效的,但我的数据没有得到更新。我的数据可能会被错误地索引吗?即使通过 Mongoose API 也可以更新实际位置。

【问题讨论】:

当人们给出简单的解释时,您是否愿意再次尝试选择一个不会冒犯任何人或以其他方式让您难堪的标题?当然,这个解释是ObjectId("56d8c73314fbc7e702cfb8c4")。哎呀,你忘了投你的字符串。 @BlakesSeven 将标题固定为更合适的问题。 ObjectId() 只出现在我的 mongo shell 中。没有它,API 会生成一个 ID。我已经编辑了我的问题以反映这一点。 什么 API?您的所有示例(以及每个错误和响应)都是从 MongoDB shell 发出的。您在查询中传递给_id 的值必须是ObjectId,否则它们将不匹配。这正是这里发生的事情。只有像 mongoose 这样的东西会自动转换一个字符串,因为它是你的模式类型,但你没有在猫鼬中执行任何示例。 @BlakesSeven 我认为可以尝试一下 @BlakesSeven 成功了!您介意提交一个答案,以便我将我的愚蠢问题归功于您吗? 【参考方案1】:

请知悉db.collection.update( criteria, objNew, upsert, multi )

    criteria:匹配条件 objNew:更新内容 upsert:对或错 true : 如果不存在,插入它 false : 如果不存在,不要插入 multi:对或错 true : 更新所有匹配的文档 false : 只更新第一个匹配的文档

【讨论】:

对不起,这是我的第一个答案。我不熟悉这个论坛。我可以尽快熟悉这个【参考方案2】:

你可以通过 $push 或 $addToSet 来实现。

db.col.update(
         name: 'reviews', 'list.id': 2 , 
        $push: 'list.$.items': id: 5, name: 'item5'
    )

参见mongodb手册中的参考

https://docs.mongodb.org/manual/reference/operator/update/push/

【讨论】:

以上是关于如何更新 MongoDB 中的子文档?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 C# 驱动程序更新 MongoDB 数组中的子文档

如何使用C#驱动程序更新MongoDB数组中的子文档

使用 findOne 更新 mongoDB 文档中的子字段并保存

如何使用php更新mongodb中具有键和值的子文档

如何使用php更新mongodb中具有键和值的子文档

如何将数据保存到 mongodb 中的子文档中?我正在将农场子文档转换为 null