我有一个奇怪的问题,无法弄清问题是什么。错误消息无效。
我正在向服务器发送“警报”,并希望将此警报保存到数据库中已存在的“设备”中。
我发送给服务器的警报对象如下所示:
{actionTaken: "none",
dateTime: "20152111191512",
difference: 4.88,
timestamp: 1448128894781}
设备的架构如下:
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”对象推送到我的设备的alarm-array时,我会收到异常/错误。
错误说:对于路径“报警”
的值“[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}
你有什么想法吗?
对我来说这没有任何意义。数组及其内容(对象)在Schema中指定。为什么整个对象有一个字符串转换错误值?
我用的是什么:
"express": "3.2.6",
"express-session":"1.7.6",
"hjs": "*",
"mongoose": "4.0.5",
"nodemailer": "1.4.0"
编辑:我不想使用嵌套架构。也可以使用数组来完成它。我在其他一些Schema中使用数组。
编辑2 : 我添加了一个属性“lastAlarm”并执行
device.lastAlarm = alarm;
但之后,thermometer.lastAlarm仍未定义...但是闹钟是一个对象。那么设备对象可能会被锁定吗?
答案 0 :(得分:5)
我会将alarm声明为自己的架构,并将alarm属性设置为警报数组subdocuments。这将允许您向警报架构添加验证等。注意:子文档在保存父文件之前不会保存。
http.createServer = function (cb) {
if (cb()) { /* do something */ }
};
答案 1 :(得分:2)
哇,晚了 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"
} ]
});
因此对于嵌套对象,您需要使用 field: {type: String}
而不是 field: String
答案 2 :(得分:1)
猫鼬将模式中具有键“类型”的模式中的对象解释为该对象的类型定义。
deviceId: {
type : String,
index : {
unique : true,
dropDups : true
}
}
因此,对于此架构,猫鼬将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
答案 3 :(得分:1)
也许为时已晚,但是这里的猫鼬假设deviceId不是对象,并且类型为String
deviceId: {
type : String,
index : {
unique : true,
dropDups : true
}
},
简单的解决方案:
deviceId: {
type: {
type: String
},
index: {
unique: true,
dropDups: true
}
},
答案 4 :(得分:0)
var deviceSchema = new Schema({
deviceId: {
type : String,
index : {
unique : true,
dropDups : true
},
alarms : {type: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Alarm' }]}
});
var alarmSchema = new Schema({
timestamp : Number,
dateTime : String, //yyyymmddhhss
difference : Number,
actionTaken : String, //"send sms"
});
我建议为警报制作自己的架构。我想你不能像你一样在模式中定义一个数组。
答案 5 :(得分:0)
使用内部架构解决此问题,
var SchemaObject = require('node-schema-object');
// Create custom basic type
// Type can be extended with more properties when defined
var NotEmptyString = {type: String, minLength: 1};
// Create sub-schema for user's Company
var Company = new SchemaObject({
startDate: Date,
endDate: Date,
name: NotEmptyString
});
// Create User schema
var User = new SchemaObject({
// Basic user information using custom type
firstName: NotEmptyString,
lastName: NotEmptyString,
// "NotEmptyString" with only possible values as 'm' or 'f'
gender: {type: NotEmptyString, enum: ['m', 'f']},
// Index with sub-schema
company: Company,
// An array of Objects with an enforced type
workHistory: [Company],
// Create field which reflects other values but can't be directly modified
fullName: {type: String, readOnly: true, default: function() {
return (this.firstName + ' ' + this.lastName).trim();
}}
});
// Initialize a new instance of the User with a value
var user = new User({firstName: 'Scott', lastName: 'Hovestadt', gender: 'm'});
// Set company name
user.company.name = 'My Company';
// The date is automatically typecast from String
user.company.startDate = 'June 1, 2010';
// Add company to work history
user.workHistory.push({
name: 'Old Company',
startDate: '01/12/2005',
endDate: '01/20/2010'
});
console.log(user.toObject());
// Prints:
{ firstName: 'Scott',
lastName: 'Hovestadt',
gender: 'm',
company:
{ startDate: Tue Jun 01 2010 00:00:00 GMT-0700 (PDT),
endDate: undefined,
name: 'My Company' },
workHistory:
[ { startDate: Wed Jan 12 2005 00:00:00 GMT-0800 (PST),
endDate: Wed Jan 20 2010 00:00:00 GMT-0800 (PST),
name: 'Old Company' } ],
fullName: 'Scott Hovestadt' }