我想知道如何最好地解决以下结构/场景,我们将嵌套架构作为真实来源并想要引用它。
架构:
Picks[]
注意:我省略了大多数不必要的字段。
游戏
var gameSchema = new Schema({
dateTime: Date,
location: String,
homeTeam: String,
awayTeam: String
});
比赛
var contestSchema = new Schema({
schedule: [{
week: Number,
games: [gameSchema],
}]
});
使用Picks[]
var pickSchema = new Schema({
week: Number,
team: String,
game: {
type: Schema.Types.ObjectId,
ref: 'Game'
}
});
var ticketSchema = new Schema({
contest: {
type: Schema.Types.ObjectId,
ref: 'Contest'
},
picks: [pickSchema]
});
以下是我必须解决的一些想法:
游戏架构作为自己的集合
我们可以将Games
移动到自己的集合中,然后只需引用Contest
和Ticket.Pick
中的游戏,就像{ type: Schema.Types.ObjectId, ref: 'Game'}
一样。
但是,如果我认为在查找Games
时我总是需要Contests
,我们会希望在Contests
内留下真相来源,如果我理解正确的话。
跳过参考,并仅保存游戏的ObjectId
对于这个,我们想要略微重写PickSchema
。
var pickSchema = new Schema({
week: Number,
team: String,
game_id: Schema.Types.ObjectId
});
请注意,我们在Contest
上引用了Ticket
。这应该允许我们在Ticket
内为游戏构建类似的内容。 (未经测试,只是概念)
Ticket.findById(ticketObjectId).populate('contest').exec((err, tickets) => {
let ticket = tickets[0];
let pickedGame;
for(pick of ticket.picks) {
for(schedule of tickets.contest.schedule){
if(schedule.week === pick.week) {
for(game of schedule.games) {
if(game._id === pick.game_id) {
pickedGame = game; // Yay we found our game
}
}
}
}
}
});
我的意思是,我们可以把它放在过滤器上面,但是在一天结束时,这看起来就像是一场噩梦。
我们或许可以在populate('contest')
内运行查询,但经过一些尝试,我认为这不会给我们提供我们想要的内容。
重复游戏
鉴于游戏变化的情景相对较低。 (NFL比赛时间多久会改变一次)我们或许可以简单地将整个游戏放入Contest
和Pick
。这意味着如果游戏确实发生变化,我们必须编写一些相当繁重的函数来更新每个对象,但鉴于我们预计这种情况会相当低,这可能是一个可接受的解决方案。但是,如果有一个更好的解决方案,只有一个事实来源,我宁愿坚持下去。
将此内容打包
目前,我倾向于将Games
移动到自己的收藏中并全面引用它,这将确保单一的事实来源。