嵌入式数组中的猫鼬更新对象

Posted

技术标签:

【中文标题】嵌入式数组中的猫鼬更新对象【英文标题】:Mongoose update object in an embedded array 【发布时间】:2018-09-11 23:35:25 【问题描述】:

我想更新帖子中的评论。我首先检索看起来像这样的 post 文档。


    "_id" : ObjectId("5aac169c229f0136296407d4"),
    "title" : "First Node.js App",
    "body" : "testing 123",
    "status" : "public",
    "user" : "John Doe",
    "date" : ISODate("2017-12-21T18:30:09.779Z"),
    "comments" : [ 
        
            "commentBody" : "This is awesome! ",
            "commentUser" : ObjectId("5a3bfd5a9e65351f9c18ba18"),
            "_id" : ObjectId("5a3c02379e65351f9c18ba1a"),
            "commentDate" : ISODate("2017-12-21T18:49:27.620Z")
        ,
        
            "commentBody" : "This is second comment.",
            "commentUser" : ObjectId("5a3bfd5a9e65351f9c18gt19"),
            "_id" : ObjectId("5a3c02379e65351f9c18ba1b"),
            "commentDate" : ISODate("2017-12-21T18:49:27.620Z")
        
    ],
    "allowComments" : true

假设我想用 "_id" ObjectId("5a3c02379e65351f9c18ba1a") 更新评论。

我试过以下没有运气。

const post = await Post.findById(req.body.postID);

await post.update('comments._id' : req.body.commentID,$set : 
  'comments.$.commentBody': req.body.comment
  
);

这给了我以下错误: MongoError: cannot use the part (cmets of cmets._id) 遍历元素

任何建议将不胜感激。提前致谢!

【问题讨论】:

【参考方案1】:

你可以试试这样的::

Post.findOneAndUpdate(
 "_id": req.body.postID, "comments._id": req.body.commentID ,
     
        "$set": 
            'comments.$.commentBody': req.body.comment
        
    ,
    function(err,doc) 

    
);

【讨论】:

这可能无法逐行为您提供正确的答案。这只是一个想法。我自己对节点有点陌生 您好 Akshansh,感谢您的建议。我收到以下错误:位置运算符未从查询中找到所需的匹配项。您是否不必在某处包含要更新的评论 ID“ObjectId("5a3c02379e65351f9c18ba1a")”? @user752746 .. 看看这个***.com/questions/26156687/… 非常感谢 Akshansh,该链接非常有帮助。我现在可以更新我的评论了。 我在您的建议中添加了 ("cmets._id": req.body.commentID) 并且有效。【参考方案2】:

我不确定如何在 node.js 中实现这一点,但这里是 Mongo 查询:

db.sample.aggregate([
$match:"comments.commentUser":ObjectId("5a3bfd5a9e65351f9c18ba19"),
$redact:
     $cond:
       if:$or:[$eq:["$commentUser",ObjectId("5a3bfd5a9e65351f9c18ba19")], 
$not:"$commentUser"],
     then:"$$DESCEND",
     else:"$$PRUNE"
    

,
  $addFields:comments:$map:
                     input:"$comments",
                     as:"comment",
                     in:"commentBody":"test comment", "commentUser" : "$$comment.commentUser", "_id" :"$$comment._id", "commentDate" :"$$comment.commentDate"

    

   ,
   $out:"sample" 
])

限制文档只显示特定的用户 ID cmets。之后,添加了带有更新评论的 cmets。最后在没有更新查询的情况下替换聚合中的原始内容(请注意,如果您运行查询,集合将被替换)。我没有对此进行广泛测试,而是在我本地处理小型数据集。但是,您可能需要为此查询添加一些调整,然后检查如何将相同的查询添加到 node.js

【讨论】:

以上是关于嵌入式数组中的猫鼬更新对象的主要内容,如果未能解决你的问题,请参考以下文章

嵌入式文档的猫鼬更新

构建我的猫鼬模式的最佳方式:嵌入式数组、填充、子文档?

更新混合类型的猫鼬嵌套数组

在猫鼬中仅更改整个嵌入式文档数组的一个字段

在猫鼬中仅更改整个嵌入式文档数组的一个字段

创建包含对象数组的猫鼬模式