如果更新时某个属性的值为null,则不应将该属性添加到logging中
假设我有一个像这样的mongoose模式:
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);
我使用variablesTest来声明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"}); } }); } });
现在,如果我在数据库中保存新的logging,然后在数据库中看到它,那么它看起来像:
{ "_id" : ObjectId("ns8f9yyuo32hru0fu23oh"), //some automatically generated id "name" : "firstTest", "__v" : 0 }
现在,如果我更新同一个文件而不更改任何内容,然后如果我看看数据库中的相同logging,那么我得到:
{ "_id" : ObjectId("ns8f9yyuo32hru0fu23oh"), //some automatically generated id "name" : "firstTest", "__v" : 0, "nickName" : null }
你能看到昵称被设置为空吗? 我不希望它像这样工作。 我希望如果我的财产是空的,那么该财产不应该包括在logging中。
如果你还记得,我有控制台logging更新之前updatedValues。 (请参阅第二个代码块)。 所以,这里是logging的值:
{ "_id" : ObjectId("ns8f9yyuo32hru0fu23oh"), //some automatically generated id "name" : "firstTest" }
我不知道为什么,但昵称是不存在的logging值,然后更新后,我得到nickName: null
。 我认为,问题出在第二个Code块。 你能检查一下吗?
注意:
其实我的模式中有更多的字段比我指定的更多。 有些字段也是对其他logging的引用。
我不会这样写,但我会告诉你为什么你的代码失败。
问题是你的$ set块
你正在select专门设置值的传递更新对象。如果该值是undefined
你迫使mongo设置为null。
这是问题
例如,在DB中:
{ "_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。
我会使用mongoose插件,而不用担心手动将字段传递给模型
请参阅https://github.com/autolotto/mongoose-model-update
你可以定义可更新的字段,然后你可以这样做
model.update(req.body)
,不用担心这一切
即使你不想使用插件,你仍然可以做
Test.findByIdAndUpdate(id, { name, nickname }, callback)
问题在于你还在文档上添加了nickname
属性 – 你只是把它设置为undefined
,但是与你认为不一样的东西不一样。
你想要的是不包括昵称属性,如果它是未定义的,你可以这样做:
module.exports.updateTest = function(updatedValues, callback) { const set = { "name": updatedValues.name }; if (updatedValues.nickName) { set["nickName"] = updatedValues.nickName; } Test.update({ "_id": updatedValues.id }, { "$set": set}, { multi: false }, callback ); };
看看你的代码,你的更新方法有一个问题,不会帮助你获得你想要的结果。
这是你更新的代码:
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 ); };
问题出在$set
部分。
在MongoDB中,你不能通过给它undefined
来取消在文档中的字段。 你应该使用$unset
运算符。
所以你的更新代码应该是这样的:
module.exports.updateTest = function(updatedValues, callback) { console.log(updatedValues); //this output is shown below const operators = {$set: {name: updatedValues.name}}; if (updatedValues.nickName) { operators.$set.nickName = updatedValues.nickName; } else { operators.$unset = {nickName: 1}; } Test.update( { "_id": updatedValues.id }, operators, { multi: false }, callback ); };
请注意, $unset
的使用对于删除文档中已存在的字段是很重要的。
正如你在文档中所说的查询中使用$set
$ set操作符用指定的值replace字段的值。
所以你迫使在这里把未定义的值设置为null
。 您可以在模式的nickName
字段中设置required : true
,或者尝试传递JS对象,而不是编写原始查询,而不是:
Test.update( { "_id": updatedValues.id }, { "$set" : { "name" : updatedValues.name, "nickName" : updatedValues.nickName } }, { multi: false }, callback );
尝试做:
var data = { name : updatedValues.name }; if(updatedValues.nickName){ data.nickName = updatedValues.nickName; } Model.update({ "_id": updatedValues.id }, data ,options, callback)
请查看Mongoose文档中的这个链接,了解更多关于该方法的信息。
- 从angular度应用程序调用nodejs中的函数
- WebStorm – 使node_modules“库根”,但也从索引中排除它
- 在Node.js中,是否正在侦听EventEmitter,创build一个对它的引用?
- Sequelize-创build一个instarnce后不返回承诺
- 强制断开服务器端sockjs node.js
- Grunt:当函数不能被分割到不同的任务时,如何依次运行一个函数,然后是一个任务,然后是另一个函数?
- nodejs console.log对象
- 将全局variables传递给JavaScript中的事件callback函数?
- 你如何构buildnode.jsdynamicweb服务器? (不通知升级服务器)