我有two popular和类似的问题,但区别在于那些只需要担心一个对象的深度填充关联,而我的是N个对象。
假设我有3个模型定义(为清楚起见,省略了一些属性):
identity: 'room',
attributes: {
LocationId : { type: 'integer',
primaryKey: true,
required: true,
autoIncrement: true },
DisplayName : { type: 'string',
unique: true },
FloorId : { model: 'Floor' }
}
identity: 'floor',
attributes: {
FloorId : { type: 'integer',
primaryKey: true },
FloorName : { type: 'string' },
BuildingId : { model: 'Building' },
rooms: {collection:'room', via:'FloorId'}
}
identity: 'building',
attributes: {
BuildingId : { type: 'integer',
primaryKey: true },
BuildingName : { type: 'string' },
floors: {collection:'floor', via:'BuildingId'}
}
最终目标是拥有一个具有这种基本结构的对象数组:
[{
"LocationId": 555,
"DisplayName": 'SomeCoolName',
"Floor" : {
"FloorId": 1337,
"FloorName": '5',
"Building": {
"BuildingId": 4321,
"BuildingName": 'HQ'
}
}
}, {...}]
由于不知道 BlueBird库 承诺以及我应该这样做,我没有走得太远:
showWithAssetGeo: function(req, res) {
room.find( { assetCount: { '>': 0 } } )
.populate('FloorId')
.each(function(room){
var Building = Building.find({ id: _.pluck(room.FloorId, 'BuildingId') })
.then(function(Building) {return Building;});
return [room, Building];
})
.spread(function(room, Building) {
//Something to combine it all?
})
.catch (function(err) {
if (err) { res.badRequest('reason' + err); }
}
}
更新:必须调整下面标记的答案。 Here is the final working code.
答案 0 :(得分:2)
你需要确保通过调用then或exec来执行find(每个都不会这样做)。
好像你试图在所有楼层上映射,然后将这些承诺带回一个楼层。 Promise.all()就是这样做的。
尝试以下内容:
showWithAssetGeo: function(req, res) {
room.find( { assetCount: { '>': 0 } } )
.populate('FloorId')
.then(function(rooms) {
return Promise.all(rooms.map(function(room) {
return Building.findOne({id: room.FloorId.BuildingId})
.then(function(building) {
room.FloorId.building = building;
});
})
})
.then(function(deeplyPopulatedRooms) {
res.json(deeplyPopulatedRooms);
})
.catch(function(error) {
if (err) { res.badRequest('reason' + err); }
});
}
然而,拔掉所有可能建筑物的id并且找到所有id的id可能会更高效。但上述内容应该有效,并且似乎与您之前采用的方法一致。