我正在使用Node.js和MongooseJS编写应用程序,作为处理数据库调用的中间件。
我的问题是我有一些嵌套模式,其中一个以错误的方式填充。当我跟踪总体的每一步时 - 所有数据都很好,除了devices
数组,它是空的。我仔细检查了数据库,那个数组里面有数据,所以应该没问题。
我有Room
架构。 Room
的每个对象都有一个名为DeviceGroups
的字段。该字段包含一些信息,其中一个是名为Devices
的数组,它存储了分配给父房间的设备。
正如您在代码中看到的那样,我根据请求服务器的ID找到了一个房间。一切都很好,数据与数据库中的数据一致。问题是devices
数组是空的。
这是某种MongooseJS的怪癖,还是我在这里做错了什么,devices
数组返回空?我检查了数据库本身,里面有一些数据,所以数据很好,错误在粘贴的代码中。
代码:
架构:
const roomSchema = Schema({
name: {
type: String,
required: [true, 'Room name not provided']
},
deviceGroups: [{
type: Schema.Types.ObjectId,
ref: 'DeviceGroup'
}]
}, { collection: 'rooms' });
const deviceGroupSchema = Schema({
parentRoomId: {
type: Schema.Types.ObjectId,
ref: 'Room'
},
groupType: {
type: String,
enum: ['LIGHTS', 'BLINDS', 'ALARM_SENSORS', 'WEATHER_SENSORS']
},
devices: [
{
type: Schema.Types.ObjectId,
ref: 'LightBulb'
},
{
type: Schema.Types.ObjectId,
ref: 'Blind'
}
]
}, { collection: 'deviceGroups' });
const lightBulbSchema = Schema({
name: String,
isPoweredOn: Boolean,
currentColor: Number
}, { collection: 'lightBulbs' });
const blindSchema = Schema({
name: String,
goingUp: Boolean,
goingDown: Boolean
}, { collection: 'blinds' });
数据库通话:
Room
.findOne({ _id: req.params.roomId })
.populate({
path: 'deviceGroups',
populate: {
path: 'devices'
}
})
.lean()
.exec(function(err, room) {
if (err) {
res.send(err);
} else {
room.deviceGroups.map(function(currentDeviceGroup, index) {
if (currentDeviceGroup.groupType === "BLINDS") {
var blinds = room.deviceGroups[index].devices.map(function(currentBlind) {
return {
_id: currentBlind._id,
name: currentBlind.name,
goingUp: currentBlind.goingUp,
goingDown: currentBlind.goingDown
}
});
res.send(blinds);
}
});
}
})
答案 0 :(得分:1)
这是使用discriminator方法在单个数组中使用多个模式的示例。
const roomSchema = Schema({
name: {
type: String,
required: [true, 'Room name not provided']
},
deviceGroups: [{ type: Schema.Types.ObjectId, ref: 'DeviceGroup' }]
});
const deviceGroupSchema = Schema({
parentRoom: { type: Schema.Types.ObjectId, ref: 'Room' },
groupType: {
type: String,
enum: ['LIGHTS', 'BLINDS', 'ALARM_SENSORS', 'WEATHER_SENSORS']
},
devices: [{ type: Schema.Types.ObjectId, ref: 'Device' }]
});
// base schema for all devices
function DeviceSchema() {
Schema.apply(this, arguments);
// add common props for all devices
this.add({
name: String
});
}
util.inherits(DeviceSchema, Schema);
var deviceSchema = new DeviceSchema();
var lightBulbSchema = new DeviceSchema({
// add props specific to lightBulbs
isPoweredOn: Boolean,
currentColor: Number
});
var blindSchema = new DeviceSchema({
// add props specific to blinds
goingUp: Boolean,
goingDown: Boolean
});
var Room = mongoose.model("Room", roomSchema );
var DeviceGroup = mongoose.model("DeviceGroup", deviceGroupSchema );
var Device = mongoose.model("Device", deviceSchema );
var LightBulb = Device.discriminator("LightBulb", lightBulbSchema );
var Blind = Device.discriminator("Blind", blindSchema );
// this should return all devices
Device.find()
// this should return all devices that are LightBulbs
LightBulb.find()
// this should return all devices that are Blinds
Blind.find()
在集合中,您将在每台设备上看到__t
属性
根据使用的模式(LightBulb或Blind)
我还没有尝试过这段代码,我暂时没有使用过mongoose,但我希望它会起作用:)
更新 - 经过测试的工作示例
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var util = require('util');
const roomSchema = Schema({
name: {
type: String,
required: [true, 'Room name not provided']
},
deviceGroups: [{ type: Schema.Types.ObjectId, ref: 'DeviceGroup' }]
});
const deviceGroupSchema = Schema({
parentRoomId: { type: Schema.Types.ObjectId, ref: 'Room' },
groupType: {
type: String,
enum: ['LIGHTS', 'BLINDS', 'ALARM_SENSORS', 'WEATHER_SENSORS']
},
devices: [{ type: Schema.Types.ObjectId, ref: 'Device' }]
});
// base schema for all devices
function DeviceSchema() {
Schema.apply(this, arguments);
// add common props for all devices
this.add({
name: String
});
}
util.inherits(DeviceSchema, Schema);
var deviceSchema = new DeviceSchema();
var lightBulbSchema = new DeviceSchema({
// add props specific to lightBulbs
isPoweredOn: Boolean,
currentColor: Number
});
var blindSchema = new DeviceSchema();
blindSchema.add({
// add props specific to blinds
goingUp: Boolean,
goingDown: Boolean
});
var Room = mongoose.model("Room", roomSchema );
var DeviceGroup = mongoose.model("DeviceGroup", deviceGroupSchema );
var Device = mongoose.model("Device", deviceSchema );
var LightBulb = Device.discriminator("LightBulb", lightBulbSchema );
var Blind = Device.discriminator("Blind", blindSchema );
var conn = mongoose.connect('mongodb://127.0.0.1/test', { useMongoClient: true });
conn.then(function(db){
var room = new Room({
name: 'Kitchen'
});
var devgroup = new DeviceGroup({
parentRoom: room._id,
groupType: 'LIGHTS'
});
var blind = new Blind({
name: 'blind1',
goingUp: false,
goingDown: true
});
blind.save();
var light = new LightBulb({
name: 'light1',
isPoweredOn: false,
currentColor: true
});
light.save();
devgroup.devices.push(blind._id);
devgroup.devices.push(light._id);
devgroup.save();
room.deviceGroups.push(devgroup._id);
room.save(function(err){
console.log(err);
});
// Room
// .find()
// .populate({
// path: 'deviceGroups',
// populate: {
// path: 'devices'
// }
// })
// .then(function(result){
// console.log(JSON.stringify(result, null, 4));
// });
}).catch(function(err){
});
答案 1 :(得分:0)
您可以删除其他声明中的所有内容吗
console.log(room)
检查您的mongo商店,确保您的收藏中有数据。