【发布时间】: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()一起使用,因为它只接受_id值only。您想要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