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

Lao*_*oon 8 mongoose node.js express

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

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

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

{actionTaken: "none", 
dateTime: "20152111191512", 
difference: 4.88, 
timestamp: 1448128894781}
Run Code Online (Sandbox Code Playgroud)

该设备的架构如下:

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

我从数据库加载设备(设置了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
});
Run Code Online (Sandbox Code Playgroud)

正如您在注释中看到的那样,当我想将"newAlarm"对象推送到我的设备的alarm-array时,我会收到异常/错误.

错误说:对于路径"alarm"处的值"[object Object]",转换为字符串失败

错误对象:

   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}
Run Code Online (Sandbox Code Playgroud)

你有好主意吗?

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

我用的是什么:

"express": "3.2.6",
"express-session":"1.7.6",
"hjs": "*",
"mongoose": "4.0.5",
"nodemailer": "1.4.0"
Run Code Online (Sandbox Code Playgroud)

编辑:我不想使用嵌套的架构.也可以使用数组来完成它.我在其他一些Schema中使用数组.

编辑2:我添加了一个属性"lastAlarm"并且做了

device.lastAlarm = alarm;
Run Code Online (Sandbox Code Playgroud)

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

小智 7

也许为时已晚,但这里 mongoose 假设 deviceId 不是对象并且它是 String 类型

deviceId: {
  type : String,
  index : {
    unique : true,
    dropDups : true
  }
},
Run Code Online (Sandbox Code Playgroud)

简单的解决方案:

deviceId: {
  type: {
    type: String
  },
  index: {
    unique: true,
    dropDups: true
  }
},
Run Code Online (Sandbox Code Playgroud)


Chu*_*Jr. 7

哇,晚了 5 年,但我最近遇到了这个问题。您所需要做的就是在对象中指定嵌套路由的类型。所以你的代码将更改为:

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

因此,对于嵌套对象,您需要使用field: {type: String}而不是field: String


mr.*_*eze 6

我将将Alarm声明为其自己的架构,并将Alarms属性设置为Alarm aka 子文档数组。这将使您可以向警报架构等添加验证。注意:只有保存了父文档后,子文档才会保存。

var alarmSchema = new Schema({
        timestamp : Number,
        dateTime : String, //yyyymmddhhss
        difference : Number,
        actionTaken : String, //"send sms"

});

var deviceSchema = new Schema({
   deviceId: {
        type : String,
        index : {
            unique : true,
            dropDups : true
        }
    },
    alarms : [alarmSchema]
});
Run Code Online (Sandbox Code Playgroud)


Kri*_*vin 5

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

deviceId: {
  type : String,
  index : {
    unique : true,
    dropDups : true
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,对于此模式,猫鼬将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' }
);
Run Code Online (Sandbox Code Playgroud)

通过添加此内容,我们要求猫鼬$type用于解释键的类型,而不是默认关键字type

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