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)
哇,晚了 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
我将将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)
猫鼬将模式中具有键“类型”的模式中的对象解释为该对象的类型定义。
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
| 归档时间: |
|
| 查看次数: |
18408 次 |
| 最近记录: |