Vis*_*hal 12 javascript mongoose mongodb node.js
假设我有一个像这样的猫鼬模式:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var testSchema = new Schema({
    name: {type: String, required: true},
    nickName: {type: String}
});
var Test = module.exports = mongoose.model('Test', testSchema);
我使用变量Test声明了CRUD操作的方法.从那一个这样的方法是更新,其定义如下:
module.exports.updateTest = function(updatedValues, callback) {
    console.log(updatedValues); //this output is shown below
    Test.update(
        { "_id": updatedValues.id },
        { "$set" : { "name" : updatedValues.name, "nickName" : updatedValues.nickName } },
        { multi: false },
        callback
    );
};
现在,我在我的节点路由器中使用此方法,如下所示:
router.put('/:id', function(req, res, next) {
    var id = req.params.id,
    var name = req.body.name,
    var nickName = req.body.nickName
    req.checkBody("name", "Name is required").notEmpty();
    var errors = req.validationErrors();
    if(errors) { ........ }
    else {
        var testToUpdate = new Test({
            _id: id,
            name: name,
            nickName: nickName || undefined
        });
        Test.updateTest(testToUpdate, function(err, result) {
            if(err) { throw(err); }
            else { res.status(200).json({"success": "Test updated successfully"}); }
        });
    }
});
现在如果我在数据库中保存一条新记录然后在数据库中看到它,那么它看起来像:
{
    "_id" : ObjectId("ns8f9yyuo32hru0fu23oh"), //some automatically generated id 
    "name" : "firstTest",
    "__v" : 0
}
现在,如果我在不更改任何内容的情况下更新同一文档,那么如果我查看数据库中的相同记录,那么我得到:
{
    "_id" : ObjectId("ns8f9yyuo32hru0fu23oh"), //some automatically generated id 
    "name" : "firstTest",
    "__v" : 0,
    "nickName" : null
}
你能看到nickName被设置为null吗?我不希望它像这样工作.我希望如果我的属性为null,那么该属性不应该包含在记录中.
如果你还记得,我有控制台在更新之前记录了updatedValues.(参见第二个代码块).所以,这是记录的值:
{
    "_id" : ObjectId("ns8f9yyuo32hru0fu23oh"), //some automatically generated id 
    "name" : "firstTest"
}
我不知道为什么,但是nickName不存在于记录的值中,然后在更新后我得到nickName: null.我认为,问题在于第二个代码块.你能检查一下吗?
注意:
实际上,我的架构中的字段比我指定的字段多得多.某些字段也引用其他记录.
小智 8
您可以通过在 update 方法中将 runValidators 选项设置为 true 来阻止此类文档在 MongoDB 中更新。
前任:
  module.exports.updateTest = function(updatedValues, callback) {
    Test.update(
      { "_id": updatedValues.id },
      { "$set" : { 
        "name" : updatedValues.name, "nickName" : updatedValues.nickName } ,
      },
      { multi: false, runValidators: true },
      callback
    );
  };
此外,您还可以将选项omitUndefined设置为true以防止反映未定义的值。
前任:
  module.exports.updateTest = function(updatedValues, callback) {
    Test.update(
      { "_id": updatedValues.id },
      { "$set" : { 
        "name" : updatedValues.name, "nickName" : updatedValues.nickName } ,
      },
      { multi: false, runValidators: true, omitUndefined: true },
      callback
    );
  };
我不会这样写,但我会告诉你为什么你的代码失败了。
问题是你的 $set 块
您选择将值专门设置为传入的更新对象。如果该值是undefined您强制 mongo 将其设置为 null。
问题来了
例如,在数据库中:
{
    "_id" : ObjectId("ns8f9yyuo32hru0fu23oh"),
    "name" : "firstTest",
    "nickname": "jack",
    "__v" : 0
}
如果你通过,testToUpdate = { name: 'foo' }你最终会得到
Test.update({ ... }, { $set: { name: 'foo', nickname: undefined }}
因为你正在updatedValues.nickname摆脱争论,而那是未定义的
你想要的是什么 
Test.update({ ... }, { $set: updatedValues }翻译成Test.update({ ... }, { $set: { name: 'foo' } }.
您不再提供昵称的键,因此不会将其设置为 undefined/null。
我会使用猫鼬插件而不用担心手动将字段一直传递到您的模型
见https://github.com/autolotto/mongoose-model-update
你可以定义可更新的字段,然后你就可以做
model.update(req.body) 不用担心这一切
即使您不想使用该插件,您仍然可以这样做
Test.findByIdAndUpdate(id, { name, nickname }, callback)
| 归档时间: | 
 | 
| 查看次数: | 2860 次 | 
| 最近记录: |