【问题标题】:findOneAndUpdate() does not update valuesfindOneAndUpdate() 不更新值
【发布时间】:2020-05-17 02:01:06
【问题描述】:

我正在使用 node.js 实现一个函数来更新 mongoDB 中的值。下面是我的 mongoDB 集合,

我想更新ratings 数组中totalRatingtotalVotes 的值。因此,我在node.js中实现了如下功能。

router.post('/addReview', (req, res) => {

   Product.findOneAndUpdate(
       {_id: req.body.productId},
       {
           "$set" : {
                    "ratings.totalRating": req.body.rating,
                    "ratings.totalVotes" : req.body.votes
           }
       },
       {new : true},
       (err, productInfo) => {
           if(err) return res.json({success:false, err});
           res.status(200).json(productInfo)
       }
   )
});

下面是Product Schema,

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const AddItemsSchema = new Schema({
    _id: {type:String, required:true},
    img: {type:String, required: true},
    category: {type:String, required: true},
    name: {type:String, required: true},
    description: {type:String, required: true},
    price: {type:String, required: true},
    quantity: {type:String, required: true},
    size: {type:String, required: true},
    meterial: {type:String, required: true},
    discount:{type:Number, default: 0},
    comment:{type:Array, default: []},
    ratings:{type:Array, required: true}
});

const Products = mongoose.model('additems', AddItemsSchema);

module.exports = Products;

当我使用 postman 发送 post 请求时,它不会更新 db 值并返回 null。有人可以指出我做错了什么吗?谢谢!

邮递员请求正文,

{
    "productId": "5eb82cd3e8b80155fc3ee021",
    "rating" : 4.0,
    "votes" : 1
}

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    您的代码中有几个问题:

    1) 第一个主要问题不是更新部分,而是查询的过滤部分:

    .findOneAndUpdate(filterPart, updatePart)
    

    所以从.findOneAndUpdate() 的基本功能来看 - 它会 如果没有找到任何带有输入过滤器的文档,则返回 null。如果它找到一个文档并且由于任何原因无法更新它,那么它将返回错误或旧文档(如果查询语法没有问题并且没有执行更新)。

    也只是一个注释:当使用选项{ upsert : true } 没有{ new : true } & 如果没有匹配的文档 - 那么 结果仍将是null,尽管它会创建一个新文档。它是 因为原来findOneAndUpdate 没有找到任何文件。

    所以您的问题在于输入 req.body.productIdstring 类型,但您在数据库中的 _idObjectId() 类型,您需要在像这样查询数据库之前对其进行转换:

    const mongoose = require("mongoose");
    
    router.post("/addReview", (req, res) => {
      Product.findOneAndUpdate(
        { _id: mongoose.Types.ObjectId(req.body.productId) },
        {
          $set: {
            "ratings.0.totalRating": req.body.rating,
            "ratings.0.totalVotes": req.body.votes,
          },
        },
        { new: true },
        (err, productInfo) => {
          if (err) return res.json({ success: false, err });
          res.status(200).json(productInfo);
        }
      );
    });
    

    2) 更新部分也有问题:

    由于ratings 是一个对象数组[{},{}],你不能像下面这样:

    {
        "$set" : {
                  "ratings.totalRating": req.body.rating,
                  "ratings.totalVotes" : req.body.votes
          }
    }
    

    因为$set 运算符ratings.totalRatingratings.totalVotes 试图在ratings 下设置/创建字段totalRatingtotalVotes - 如果它是一个对象,那么它会起作用。既然不是 - 那么您需要说明您应该对数组中的哪个对象执行此更新操作,如下所示:

    {
      $set: {
        "ratings.0.totalRating": req.body.rating,
        "ratings.0.totalVotes": req.body.votes,
      },
    }
    

    从上面我们更新ratings 数组中的第一个对象。一般来说,如果总是只有 一个对象,那么将 ratings 设为 对象 而不是数组,否则如果它会有 多个对象 然后将其保留为 array 并为每个对象添加唯一值。这有助于确定在更新时使用positional 运算符时需要更新哪个特定对象。

    【讨论】:

      【解决方案2】:

      你需要提供索引来更新数组

         router.post('/addReview', (req, res) => {
      
         Product.findOneAndUpdate(
             {_id: req.body.productId},
             {
                 "$set" : {
                          "ratings.0.totalRating": req.body.rating,
                          "ratings.0.totalVotes" : req.body.votes
                 }
             },
             {new : true},
             (err, productInfo) => {
                 if(err) return res.json({success:false, err});
                 res.status(200).json(productInfo)
             }
         )
      });
      

      【讨论】:

      • 还是同样的问题。顺便说一句谢谢你的帮助
      • @MarketMAD 我已经更新了答案,如果更改架构不起作用,请保持架构不变并在查询中使用数组索引
      猜你喜欢
      • 2019-05-21
      • 2021-11-20
      • 2020-11-13
      • 1970-01-01
      • 2018-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多