如果更新时属性值为 null,则不应将该属性添加到记录中

2024-02-22

假设我有一个像这样的猫鼬模式:

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 操作的方法。其中一种方法是 update,其定义如下:

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 吗?我不希望它像这样工作。我希望如果我的属性为空,那么该属性不应包含在记录中。

如果您还记得,我在更新之前已通过控制台记录了 UpdatedValues。 (请参阅有问题的第二个代码块)。因此,这是记录的值:

{
    "_id" : ObjectId("ns8f9yyuo32hru0fu23oh"), //some automatically generated id 
    "name" : "firstTest"
}

我不知道为什么,但 nickName 不存在于记录的值中,然后更新后我得到nickName: null。我认为,问题出在第二个代码块上。您能检查一下吗?

Note:

实际上,我的模式中的字段比我在问题中指定的字段多得多。某些字段也引用其他记录。


我不会这样写,但我会告诉你为什么你的代码失败。

问题是你的 $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脱离参数并且未定义

你什么want is

Test.update({ ... }, { $set: updatedValues }

这被翻译成

Test.update({ ... }, { $set: { name: 'foo' } }

您不再为昵称提供键,因此不会将其设置为 undefined/null。


我会使用猫鼬插件,而不用担心手动将字段一直传递到您的模型(请参阅github.com/autolotto/mongoose-model-update https://github.com/autolotto/mongoose-model-update)

  • 您可以定义可更新字段,然后您就可以执行以下操作model.update(req.body)不用担心这一切
  • 即使您不想使用该插件,您仍然可以这样做Test.findByIdAndUpdate(id, { name, nickname }, callback)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果更新时属性值为 null,则不应将该属性添加到记录中 的相关文章

  • 通过 elemMatch 在 MongoDB 中排序

    MongoDB 有没有一种基于排序的方法 elemMatch 例如 我有如下所示的文档 user ObjectId fsdfsdf array of things attribute 1 ObjectId sdfsdfsd attribut
  • 如何立即启动setInterval循环? [复制]

    这个问题在这里已经有答案了 在一个简单的setInterval setInterval function Do something every 9 seconds 9000 第一个动作将在 9 秒后发生 t 9s 如何强制循环立即执行第一个
  • 设置双指缩放时精确的滚动位置

    我正在创建一个地图应用程序 它将标记图像放置在画布上并滚动到它 我正在使用浏览器的捏缩放和滚动来放大 缩小地图 然而 我注意到有一些奇怪的行为 我想知道如何解决它 这有点难以解释 但我们开始吧 假设您处于网页的标准缩放级别 无法进一步缩小
  • 此页面上的脚本导致 ie 运行缓慢

    问题就在标题中 IE 行为异常 并说有一个脚本运行缓慢 FF 和 Chrome 没有这个问题 我怎样才能找到问题所在 那个页面有很多JS 手动检查不是一个好主意 EDIT 这是我正在处理的一个项目的页面 但我需要一个工具来查找问题 End
  • 检测 Google 验证码的挑战窗口何时关闭

    我正在使用谷歌隐形验证码 有没有办法检测挑战窗口何时关闭 我所说的挑战窗口是指您必须选择一些图像进行验证的窗口 目前 我在按钮上放置了一个旋转器 一旦单击按钮 就会呈现验证码挑战 无法向用户提示另一个质询窗口 我以编程方式调用渲染函数 gr
  • React JS 服务器端问题 - 找不到窗口

    你好 我正在尝试在我的reactJS项目中使用react rte 我有服务器端渲染 每次我想使用这个包时 我都会得到 return msie 6 9 b test window navigator userAgent toLowerCase
  • 在文件之间共享 mqtt 客户端对象

    我这样连接到 MQTT mqtt js const mqtt require mqtt var options needed options var client mqtt connect mqtt someURL options clie
  • 使用 JQuery 禁用和启用所有超链接

    我有以下禁用所有超链接的内容 但在事件发生后我想再次启用它们 我该如何执行此操作 a click function return false 我认为这不仅仅是将其设置为 true 那么简单 谢谢大家 不要以这种方式绑定 点击 处理程序 而是
  • 添加要在给定命令中运行的 .env 变量

    我有一个 env 文件 其中包含如下变量 HELLO world SOMETHING nothing 前几天我发现了这个很棒的脚本 它将这些变量放入当前会话中 所以当我运行这样的东西时 cat env grep v xargs node t
  • 如果一个对象结构与另一个对象结构不匹配/不匹配,如何引发异常

    我将读取格式正确的用户输入对象 也就是说 输入对象现在可以具有接口中未定义的任何键或子结构 如果用户提供了无效的对象 我如何抛出异常 预定义接口 export interface InputStructureInterface tableN
  • 当我多次调用 requestAnimationFrame 时会发生什么

    我的意思是一次调用多个具有相同功能的 requestAnimationFrame function Draw DoSomething function AFunc prepare something requestAnimationFram
  • Web组件中嵌套槽的内容不可见

    我有一个 Web 组件 它应该接受任意元素来包装其内容 虽然我可以在 Chrome 开发工具中看到插槽已正确分配 但 DOM 中什么也没有出现 以前有人见过这个问题吗 定义 class ExampleParent extends HTMLE
  • 如何获取nodejs程序中的nodejs版本?

    In a Node js 的调试器 https github com rocky trepanjs 有一个命令显示V8版本和调试器包版本 如何获取nodejs版本 我想我基本上可以运行命令node version or nodejs ver
  • 扩展 RegExp 以获取文件扩展名

    我知道 已经有很多基于 RegExp 的解决方案 但是我找不到适合我需求的解决方案 我有以下函数来获取 URL 的各个部分 但我还需要文件扩展名 var getPathParts function url var m url match w
  • 使用 ref 触发反应 dropzone 不起作用

    我正在实现这个库 https github com felixrieseberg React Dropzone Component https github com felixrieseberg React Dropzone Compone
  • ThreeJS 中阴影的奇怪行为

    所以我有一个 ThreeJS 场景 并且添加了一些球体 多材质 我还添加了定向光 this light new THREE DirectionalLight 0xFFFFFF 1 this light position set 2 10 2
  • Jwt 签名和前端登录身份验证

    我有这个特殊的 jwt sign 函数 Backend const token jwt sign id user id process env TOKEN SECRET expiresIn 1m res header auth token
  • Chrome 扩展:强制 popup.html 关闭

    我想知道是否可以强制 popup html 关闭 在弹出的 javascript 中 window close
  • 如何映射轮播的子项数组?

    我正在尝试将 Carousel 组件包装在映射对象数组周围作为组件的子级 目前我只能让映射创建映射对象的 1 个子对象 轮播需要像这样
  • 将多维数组转换为单数组(Javascript)

    我有一个对象数组 来自 XLSX js 解析器 因此其长度和内容各不相同 表示已给予项目的资助 简化后 它看起来像这样 var grants id p 1 location loc 1 type A funds 5000 id p 2 lo

随机推荐