如何做到 findByIdAndUpdate 仅更新不为空的字段?
Happy sunshine.
如果要根据传入的参数来更新目标文档的部分数据要怎么做呢?
例如我传入了 creator, 就只更新 creator. 而不是将 update 对象内容全部更新. 同理, 传入 name 就只更新 name.
现在 MongoDB 的 $set 似乎还是得一次性指定所有要更新的参数, 而不能根据传入的值是否为空来确定是否要更新.
类似于 MyBatis 里面的 UpdateSchemaSelective()
谢谢~
如果我这样的想法本身有问题, 请指正, 谢谢~
5 回复
@ravenwang 不用封装用个最简单的方法 使用underscorejs 中的extend方法
extend_.extend(destination, *sources)
复制source对象中的所有属性覆盖到destination对象上,并且返回 destination 对象. 复制是按顺序的, 所以后面的对象属性会把前面的对象属性覆盖掉(如果有重复).
_.extend({name: 'moe'}, {age: 50});
=> {name: 'moe', age: 50}
取出来的数据用 extend 方法把新更新的数据合并再使用 findByIdAndUpdate
更新。
@ravenwang @jaywcjlove 谢谢 汗, 为了搞定这个问题, 我弄了一个方法来根据传入的参数创建对象, 我再看看你们的办法.
/**
* Convert a series of arguments to an object,
* arguments length should be a even number.
* @returns {{}} the generated Object
*/
exports.constructObj = function () {
var obj = {};
// TODO throw???
if (arguments.length % 2 != 0) {
throw new Error('Arguments length should be an even number: ' + arguments);
}
for (var i = 0; i < arguments.length; i++) {
if (arguments[i + 1]) {
obj[arguments[i]] = arguments[i + 1];
}
i++;
}
return obj;
};
调用方法:
helper.constructObj(
'email', req.body.email,
'password', req.body.password,
'avatar', req.body.avatar,
'nickname', req.body.nickname,
'sex', req.body.sex
)