【问题标题】:Push an object into array if not already present, otherwise update如果对象不存在,则将对象推送到数组中,否则更新
【发布时间】:2019-10-08 17:18:31
【问题描述】:

在基于 express 的 node.js 服务器中,通过 mongoose 与 mongo db 交互,我想仅当用户(由他的 id 标识)尚未查看时在“reviews”数组上插入“review”产品,否则,更新之前插入的评论。 给定以下 mongo 方案:

产品:

var ProductSchema = new Schema({
  ownerId: {
    type: Schema.ObjectId,
    required: 'Owner of recharge point required'
  },
  name: {
    type: String,
    required: 'The name is required'
  },      
  description: {
    type: String
  },
  reviews: {
    type: [Review]
  }
});

评论:

  var ReviewSchema = new Schema({
  reviewerId: {
    type: ObjectId,
    required: 'Reviewer id required',
    ref: 'User' <not showed>
  },
  review: {
    type: String
  },
  date: {
    type: Date, 
    default: Date.now
  }
});

这是我想出的结果,但这只是插入新评论,还没有更新它们。 我认为我的解决方案可以改进(和简化)很多。

exports.review_product = function (req, res) {
    const review = req.body.review;
    const reviewerId = req.body.reviewerId;
    const productId = req.params.productId;

    Product.findOne({_id: productId}, function(error, result){
          if(error) {
               res.status(500).send({message: error}).end()
           } else if(result){
               var newReview = new Review({ reviewerId: reviewerId, review: review});
               Product.findOneAndUpdate({ _id: productId, 'reviews.reviewerId': { $ne: reviewerId }}, 
                 { $push: { 'reviews': newReview}},
                 function(error, found) {
                     if (error) {
                        res.status(500).send({message: error}).end()
                     } else if(found) {
                        res.status(200).send({message: 'Review succefully added.'}).end()
                     } else {
                        res.status(404).send({message: 'You already reviewed this product'}).end()
                     }
              });
           } else {
               res.status(404).send({message: 'Cannot find the product to be reviewed.'}).end()
           }
  })
};

【问题讨论】:

    标签: javascript mongodb mongoose


    【解决方案1】:

    最好的方法是使用 mongoose 进行查询,以先检查产品的评论者 ID。您还可以使用 async/await 使您的代码更具可读性。

    它可能看起来像(请注意这是伪代码):

    exports.reviewProduct = async (req, res) => {
        const review = req.body.review;
        const reviewerId = req.body.reviewerId;
        const productId = req.params.productId;
    
        const hasReviewed = await Product.find({_id: productId, 'reviews.reviewerId': { $eq: reviewerId } )
    
        if(hasReviewed) {
            Product.findOneAndUpdate({
                _id: productId, 
                reviews: { $elemMatch: { reviewerId: reviewerId } }
                },
                { $set: {
                    'review.$.title': review.title,
                    'review.$.body': review.body
                 }},
                 {'new': true, 'safe': true, 'upsert': true})
        } else {
            Product.findOneAndUpdate(
                { _id: productId }, 
                { $push: { reviews: review } },
                {safe: true, upsert: true, new : true},
                (err, model) => {
                   console.log(err);
                })
        }
    }
    

    【讨论】:

      【解决方案2】:

      可以使用includes()函数

      例如:

      var array = ["a","b","c"];
      console.log(array.includes("a"); //return true
      console.log(array.includes("z"); //return false because is not exist
      

      只需将变量字符串替换为您的对象,使其适应您的代码

      【讨论】:

        猜你喜欢
        • 2019-09-15
        • 2017-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-29
        • 2018-08-09
        • 1970-01-01
        • 2014-05-15
        相关资源
        最近更新 更多