MongooseJS 在填充后返回空数组
Posted
技术标签:
【中文标题】MongooseJS 在填充后返回空数组【英文标题】:MongooseJS returning empty array after population 【发布时间】:2018-06-04 13:19:02 【问题描述】:我正在编写一个使用 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);
);
)
【问题讨论】:
我不认为您定义devices
的方式是正确的。在一个数组中拥有多个模式引用的一种方法是使用discriminator 看到这个answer
@Molda 你能提供一个简单的例子吗?当然,discriminator
正是我要找的,但你链接的另一篇文章有点复杂,因为它使用了所有中间件,对我来说不是很清楚。你能想出一个在我的例子中如何使用它的例子吗?谢谢
【参考方案1】:
你能删除你 else 语句中的所有内容吗?
console.log(room)
检查您的 mongo 商店以确保您的集合中有数据。
【讨论】:
我在发布问题之前已经这样做了。正如我在帖子中所写 - 我检查了数据库并保存了正确的 id 引用,我记录了room
并且所有内容都正确填充,除了 devices
数组为空【参考方案2】:
这是使用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
属性
根据使用的模式(灯泡或盲)使用值
我还没有尝试过代码,也有一段时间没有使用猫鼬了,但我希望它能工作:)
更新 - 经过测试的工作示例
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)
);
【讨论】:
你提议调用函数util.inherits(DeviceSchema, Schema);
。我的问题是:util
是什么?我没有看到它在任何地方宣布。它是像 NPM 的另一个包还是像 mongoose 本身的东西?
我使用了您的解决方案,但我仍然得到一个空数组。我检查了数据库,数据保存在那里。这是输出: [ _id: undefined, name: undefined, goingUp: undefined, goingDown: undefined ]
util
是内置模块,只需要它var util = require('util')
谢谢!您提供的示例有效!此外,它帮助我更好地理解了discriminator
和mongoose
本身。我还需要在discriminator
上做一些工作,但是,多亏了你,我离我更近了!
我很高兴能帮上忙。还有一个我想指出的。 Room.find 调用填充设备组和设备将对 db 进行 3 次单独调用,因为它需要查询 3 个集合。如果可能的话,我肯定会尝试通过完全避免设备组来简化它。这只是我的看法,但需要牢记。以上是关于MongooseJS 在填充后返回空数组的主要内容,如果未能解决你的问题,请参考以下文章