MongoDB / Mongoose:使用findOneAndUpdate()更新整个文档

时间:2016-06-14 23:27:54

标签: javascript mongodb mongoose

我想使用findOneAndUpdate()方法创建一个不存在的文档,或者如果存在则更新它。请考虑以下代码:

       SampleComment = new Comment({
            id: '00000001',
            name: 'My Sample Comment',
            ...
        })

这是我试图找出SampleComment是否已经存在,如果存在,请更新它,否则创建它:

        Comment.findOneAndUpdate(
            { id: SampleComment.id }, 
            { SampleComment }, // <- NOT PASSING THE OBJECT
            { upsert: true, setDefaultsOnInsert: true }, 
            function(error, result) {
                ...
        });

我正在尝试将Model-instance作为第二个参数中的对象传递,但结果只返回模型的默认值。文件本身也是如此。

如何在第二个参数中正确传递整个对象SampleComment

3 个答案:

答案 0 :(得分:3)

当您使用findOneAndUpdate()作为Document对象作为更新对象而调用{ SampleComment }时,实际上正在发生的事情是将其分解为SampleComment : {...}

然后,猫鼬会去查看您的数据库文档中名为SampleComment的任何属性,什么都不找到,然后什么也不做。返回给您的文档原封不动。

解决此问题的方法是,首先使用Mongoose的toObject()方法将文档转换回普通更新对象,然后删除_id(因为该属性是不可变的,并且您不想无论如何都要用更新替换它),然后用现有的findOneAndUpdate()方法保存它。例如:

let newComment = SampleComment.toObject();
delete newComment._id;

Comment.findOneAndUpdate(
    { id: SampleComment.id }, 
    newComment,
    { upsert: true, setDefaultsOnInsert: true }, 
    function(error, result) {
        ...
    }
);

然后您可以在数据库中查看更新的文档。要在result中接收更新的文档,还需要将选项{ new: true }传递给选项对象。

这是Mongoose的toObject()文档方法文档的链接。

答案 1 :(得分:2)

默认情况下,返回的结果将是未更改的文档。如果要返回新的更新文档,则必须传递名为new的附加参数,其值为true

Comment.findOneAndUpdate({id: SampleComment.id}, SampleComment, {new: true, upsert: true, setDefaultsOnInsert: true}, function(error, result) {
    if(error){
        console.log("Something wrong when updating data!");
    }

    console.log(result);
});

请参阅http://mongoosejs.com/docs/api.html#query_Query-findOneAndUpdate

function(error, doc) {
  // error: any errors that occurred
  // doc: the document before updates are applied if `new: false`, or after updates if `new = true`
}

答案 2 :(得分:0)

我找到了方便快捷的方法:D

就我而言,我只需要从表单中插入对象并更新文档。也许这有助于某人:

Angularjs控制器:

  $scope.bike ={};
  fBikeFactory.get({
        id:$stateParams.id
      })
      .$promise.then(function (response) {
        $scope.bike = response;
      },function (response) {
        $scope.bike = "Error: " + response.status + " " + response.statusText;
      });


// UPDATE a BIKE
      $scope.saveBike = function() {
        $scope.processing = true;

        var updateQuery = fBikeFactory.update({id: $stateParams.id}, $scope.bike);
        updateQuery.$promise.then(function(rep) {
            $scope.processing = false;
            $scope.message = "Desat amb èxit";
            setTimeout(function(){ $state.go('home.adminBikes');$scope.bike.message = ''; }, 750);
        },function(err) {
            $scope.processing = false;
            $scope.message = 'Error al Desar, torna a provar-ho.';
        })
      };

需要型号:

var Bike = require('../models/bikeModel.js');

...

<强> ROUTE:

bikesRouter.route('/bikes/:id')
    .put(function(req,res) {


    Bike.findOneAndUpdate(
            {_id: req.params.id}, // find a document with that filter
            req.body, // document to insert 
            {upsert: true, new: true, runValidators: true}, // options
            function (err, updatedBike) { // callback
                if (err) console.log('ERROR '+ err);
                else res.json(updatedBike)

            }
        );
    });

希望有所帮助:D