【问题标题】:Having trouble finding/or implementing the correct mongoDb method to find and update subdocument [duplicate]无法找到/或实施正确的 mongoDb 方法来查找和更新子文档 [重复]
【发布时间】:2019-08-19 13:39:17
【问题描述】:

我正在尝试根据其 Id 和父文档的 Id 更新子文档中的特定字段。我是新手,所以我可能会误解 mongoDb 文档,但据我所知 findOneAndUpdate 应该可以工作。我也尝试过仅更新、updateOne 以及 findByIdAndUpdate。我尝试过的任何方法都没有成功更新我的对象。

我正在尝试更新 savedBeers 数组中特定对象的评分值。

这是我的模型:

{
    "_id": {
        "$oid": "5c97cf50cc81525a75eb6c19"
    },
    "email": "email@gmail.com",
    "password": "$2b$10$6ixbu2Ka.Zj0eE5kF21MLO6CiMblgu4D6IHiC7Ta52o.cZFMNw1Mm",
    "__v": 0,
    "savedBeers": [
        {
            "id": 2,
            "comment": null,
            "rating": 0
        },
        {
            "id": 4,
            "comment": null,
            "rating": 0
        }
    ]
}

前端:

function addRating(beerId, ratingValue){
    let userId= localStorage.userId
    console.log(beerId, userId, ratingValue);
    $.ajax({
        type: "PUT",
        url: `/user/${userId}/${beerId}/${ratingValue}`,
        success: addRatingSuccess,
        error: addRatingError
    });
    function addRatingSuccess(response) {
        console.log("added", response);
    }
    function addRatingError() {
        console.log("error");    
    }
}

后端 userController.js:

 addRating:(req,res)=>{
            console.log(req.params);
            req.params.beerId = parseInt(req.params.beerId)
            req.params.ratingValue = parseInt(req.params.ratingValue)
            db.User.findOneAndUpdate(
                 {_id: ObjectId(req.params.userId), "savedBeers.id": req.params.beerId },
                { $set: { 'savedBeers.$.rating' : req.params.ratingValue } },
                {new:true})
                .exec(function (err, doc){
                    if (err){
                        console.log(err);
                        res.json({
                            "error": err
                        })
                    } else {
                        console.log(doc);
                        res.json({
                            doc
                        })
                    }
                }) 
        }

这是我在前端得到的响应:

added 
{doc: {…}}
doc:
email: "email@gmail.com"
savedBeers: Array(2)
0: {id: 2, comment: null, rating: 0}
1: {id: 4, comment: null, rating: 0}
length: 2
__proto__: Array(0)
__v: 0
_id: "5c97cf50cc81525a75eb6c19"
__proto__: Object
__proto__: Object

还有后端:

{ userId: '5c97cf50cc81525a75eb6c19', beerId: 4, ratingValue: 3 }
{ savedBeers:
   [ { id: 2, comment: null, rating: 0 },
     { id: 4, comment: null, rating: 0 } ],
  _id: 5c97cf50cc81525a75eb6c19,
  email: 'email@gmail.com',
  __v: 0 }


非常感谢您抽出宝贵时间。如果有任何其他有用的信息,请告诉我。

【问题讨论】:

  • 我也尝试过该解决方案。也不行。编辑我的帖子以反映这一点。
  • 为世界上其他人工作,并且已经这样做了很多年。另请注意,您不能将多字段谓词与findByIdAndUpdate() 一起使用,因为它只接受_idonly。您想要 findOneAndUpdate() 而不是您通常也想要 new: true 。不会重新打开,因为链接的答案确实是答案,只是你仍然做错了。再次阅读答案和链接文档。
  • 是的,这很奇怪,因为它不起作用。了解 findOneAndUpdate 和新的:true。根据我的眼光:db.your_collection.update( { _id: ObjectId("your_objectid"), "Statuses.Type": 1 }, { $set: { "Statuses.$.Timestamp": "new timestamp" } } ) 看起来和这个差不多:db.User.findOneAndUpdate( {_id: ObjectId(req.params.userId), "savedBeers.id": req.params.beerId }, { $set: { 'savedBeers.$.rating' : req.params.ratingValue } }, { new:true})}
  • 您现在在帖子中显示的最后一件事就是您收到的回复。请参阅n: 0。这意味着没有匹配项您使用的是普通节点驱动程序,因此findByIdAndUpdate 之类的内容甚至无效。
  • "savedBeers.id": parseIntr(req.params.beerId) - 这就是你一直需要的问题parseInt()。与使用它的 ObjectId() 一样重要,出于同样的原因,req.params 是“字符串”**,因此您需要转换它们。让我感到震惊的是您在问题中对findByIdAndUpdate() 的使用,这是一种猫鼬方法,而不是该驱动程序的一部分。 Mongoose 具有将查询谓词中的值“自动转换”为预期类型的​​模式定义。对于其他任何事情,您都可以手动完成。

标签: javascript node.js mongodb express subdocument


【解决方案1】:

您似乎在“{ $set: { 'savedBeers.$' : req.params.ratingValue }”中的“savedBeers.$”之后缺少“.rating”

所以那行应该是 "{ $set: { 'savedBeers.$.rating' : req.params.ratingValue }"

【讨论】:

  • 感谢您的回复。我也试过了。结果相同。
猜你喜欢
  • 1970-01-01
  • 2020-08-09
  • 1970-01-01
  • 1970-01-01
  • 2011-03-23
  • 2023-01-30
  • 2020-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多