javascript - 填充后 MongooseJS 返回空数组

标签 javascript node.js mongoose

我正在编写一个应用程序,使用 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);
            }
        });
    }
})

最佳答案

这是使用 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 属性 根据使用的模式(灯泡或百叶窗)使用值

我还没有尝试过代码,也有一段时间没有使用 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){

});

关于javascript - 填充后 MongooseJS 返回空数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47932144/

相关文章:

javascript - 如何更改嵌套( Mongoose )回调中的 json 值

php - 确认警报不起作用

javascript - 在表单发布上调用 Javascript 以通过 jQuery 更新 UI

javascript - 更改 Highcharts Drag 的步长?

node.js - req.headers.origin 未定义

node.js - 当mongodb不在同一个VM中时,mongodb连接超时

javascript - Firefox 有时无法在 Canvas 中加载图像

javascript - 显示从nodejs服务器发送的文件数据,就像在angularjs中一样

node.js - 安装时出错 "npm install -g ionic cordova"

javascript - Mongoose 查找并从文档数组中删除对象