如果存在则更新其他插入图片上传

时间:2016-11-12 18:33:19

标签: javascript node.js mongodb amazon-s3 mongoose

我已经创建了以下代码,但是如果findOneAndUpdate找到结果,我似乎无法弄清楚如何更新图像,并且在put_form_url之前似乎正在执行result.save。如何实现这样的功能,如果它存在,它将更新所有属性并将新图像上传到s3,如果不存在,它将创建一个带有s3上传的新对象。

router.post('/:id/:name/:birth/:country/:image', function(req, res, next) {

var params = req.params;
var accessHeader = req.headers;

process.env.AWS_ACCESS_KEY_ID=''
process.env.AWS_SECRET_ACCESS_KEY=''
AWS.config.region = 'eu-west-1';
var s3 = new AWS.S3();


User.findOneAndUpdate({"_id": params.id},  {$set:{"name": params.name, "birthday": params.birth, "country": params.country}}, {new: true}, function(error, result) {
  if (!error) {
      // If the document doesn't exist
      if (!result) {
          // Create it

          put_from_url(params.image, new Date().toString, function(err, res) {

            result = new User({
              _id: params.id,
              name: params.name,
              birthday: new Date(params.birth),
              country: params.country,
              image: "url" + params.id
            });
          });


      }
      // Save the document
      result.save(function(error) {
          if (!error) {
              res.json({ message: 'User created!' });
          } else {
              res.send(err);
          }
      });
    }
  });




});

上传功能

function put_from_url(url, key, callback) {
    request({
        url: url,
        encoding: null
    }, function(err, res, body) {
        if (err)
            return callback(err, res);

        uploader.putObject({
            Bucket: "",
            Key: "/" + key,
            ContentType: res.headers['content-type'],
            ContentLength: res.headers['content-length'],
            Body: body // buffer
        }, callback);
    })
}

1 个答案:

答案 0 :(得分:0)

好的,似乎你有两个问题。

  1. 如果没有用户,如何实现它以存储图像;如果已经有用户,如何更新它?
  2. 因此,在任何一种情况下,您都必须存储图像,所以为什么不先做更新图像然后更新/插入用户或反之亦然。我个人会选择前者。

    router.post('/:id/:name/:birth/:country/:image', function(req, res, next) {
    
    var params = req.params;
    var accessHeader = req.headers;
    
    process.env.AWS_ACCESS_KEY_ID=''
    process.env.AWS_SECRET_ACCESS_KEY=''
    AWS.config.region = 'eu-west-1';
    var s3 = new AWS.S3();
    
         put_from_url(params.image, params.id, function(err, res) {
    
                result = new User({
                  _id: params.id,
                  name: params.name,
                  birthday: new Date(params.birth),
                  country: params.country,
                  image: "url" + params.id
                });
                // Save the document
                result.save(function(error) {
                   if (!error) {
                      res.json({ message: 'User created!' });
                    } else {
                      res.send(err);
                    }
                });
              });
    

    很少有注意事项,对于您使用日期的密钥,我只是使用了id,以便稍后可以使用新图像进行更新。可以使用唯一键来使用和更新s3对象。如果您想要保留旧图像副本,最好使用像params.id/(new Date().toString)这样的密钥,这样旧的图像就不会被覆盖

    其次,如果基于_id的对象存在,则保存函数固有地更新,否则它会创建一个新的。

    1. 看起来像在put_form_url之前执行了result.save
    2. 肯定会,javascript本质上是异步的,这意味着如果一个代码占用太长时间,它将执行下一个语句。当你调用s3时,它的I / O调用将尝试将图像上传到s3并将被处理,同时你的下一行代码将在你的情况下执行result.save。

      有两种方法。 I>在前一次调用的回调中包装下一个调用。并且更好和更优越的ii>使用承诺。

      Promise是一种未来事件,您可以告诉上传到s3 然后保存到数据库中。

      承诺几乎没有什么学习曲线,但它很棒,干净而且真的很有帮助。 q是一个这样的承诺模块。