Mongoose Schema 错误:将对象推送到空数组时“转换为字符串失败”

新手上路,请多包涵

我有一个奇怪的问题,无法弄清楚问题是什么。错误消息没有帮助。

我正在向服务器发送“警报”,并希望将此警报保存到数据库中已经存在的“设备”中。

我发送到服务器的警报对象如下所示:

 {
  actionTaken: "none",
  dateTime: "20152111191512",
  difference: 4.88,
  timestamp: 1448128894781
}

该设备的 Schema 如下:

 var deviceSchema = new Schema({
   deviceId: {
        type : String,
        index : {
            unique : true,
            dropDups : true
        }
    },
    alarms : [ {
        timestamp : Number,
        dateTime : String, //yyyymmddhhss
        difference : Number,
        actionTaken : String, //"send sms"
    } ]
});

我从数据库加载设备( deviceId 已设置):

 Thermometer.findOne({
        deviceId : deviceId
}, function(error, device){
   //error handling
   var now = (new Date().getTime());
   var nowDateTime = (new Date()).toISOString().slice(0, 19).replace(/[-T\s:]/g, "");
   var newAlarm = {
       timestamp : now,
       dateTime : nowDateTime, // yyyymmddhhmmss
       difference : diff,
       actionTaken : "none"
   };
   device.alarms.push(newAlarm);  //EXCEPTION !

   //       device.save //doesn't get called
});

正如您在评论中看到的那样,当我想将“newAlarm”对象推送到设备的警报阵列时,我得到一个异常/错误。

错误说:

对于值 [object Object] 在路径 alarms 转换为字符串失败

错误对象:

    kind: "string",
   message: "Cast to string failed for value "[object Object]" at path "alarms"",
   name: "CaseError",
   path: "alarms",
   stack: undefined,
   value: {actionTaken: "none", dateTime: "20152111191512", difference: 4.88, timestamp: 1448128894781}

你有想法吗?

对我来说这没有任何意义。数组及其内容(对象)在 Schema 中指定。为什么将整个对象作为值存在字符串转换错误?

我用什么:

 "express": "3.2.6",
"express-session":"1.7.6",
"hjs": "*",
"mongoose": "4.0.5",
"nodemailer": "1.4.0"


编辑: 我不想使用嵌套模式。也可以用数组来做。我用其他一些模式中的数组来做。

编辑 2 :我添加了一个属性 lastAlarm 并执行

device.lastAlarm = alarm;

但在那之后, thermometer.lastAlarm 仍然未定义……但 alarm 是一个对象。那么设备对象有可能被锁定吗?

原文由 Laokoon 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 654
1 个回答

Mongoose 将模式中具有键“type”的模式中的对象解释为该对象的类型定义。

 deviceId: {
  type : String,
  index : {
    unique : true,
    dropDups : true
    }
}

因此,对于此模式,mongoose 将 deviceId 解释为 String 而不是 Object,并且不关心 deviceId 中的所有其他键。

解决方案:

将此选项对象添加到模式声明 { typeKey: '$type' }

 var deviceSchema = new Schema(
{
   deviceId: {
        type : String,
        index : {
            unique : true,
            dropDups : true
        }
    },
    alarms : [ {
        timestamp : Number,
        dateTime : String, //yyyymmddhhss
        difference : Number,
        actionTaken : String, //"send sms"
    } ]
},
{ typeKey: '$type' }
);

通过添加这个,我们要求猫鼬使用 $type 来解释键的类型而不是默认关键字 type

猫鼬文档参考: https ://mongoosejs.com/docs/guide.html#typeKey

原文由 Krishna Pravin 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题