关系数据库devise到mongoDB / mongoosedevise

我最近开始使用mongoDB和mongoose为我的新的node.js应用程序。 在我努力适应mongoDB / noSQL思维方式(如非规范化和缺乏外键关系)之前,只使用了关系数据库。 我有这个关系数据库devise:

**Users Table** user_id username email password **Games Table** game_id game_name **Lobbies Table** lobby_id game_id lobby_name **Scores Table** user_id game_id score 

所以,每个大厅都属于一个游戏,多个大厅可以属于同一个游戏。 用户对不同的游戏也有不同的分数。 到目前为止,我的用户架构,我有以下几点:

 var UserSchema = new mongoose.Schema({ username: { type: String, index: true, required: true, unique: true }, email: { type: String, required: true }, password: { type: String, required: true } }); 

所以我的问题是,我将如何将关系devise构造成mongoDB / mongoose模式? 谢谢!


编辑1

我现在试图创build所有的模式,但我不知道这是否正确的方法。

 var UserSchema = new mongoose.Schema({ _id: Number, username: { type: String, index: true, required: true, unique: true }, email: { type: String, required: true }, password: { type: String, required: true }, scores: [{ type: Schema.Types.ObjectId, ref: 'Score' }] }); var GameSchema = new mongoose.Schema({ _id: Number, name: String }); var LobbySchema = new mongoose.Schema({ _id: Number, _game: { type: Number, ref: 'Game' }, name: String }); var ScoreSchema = new mongoose.Schema({ _user : { type: Number, ref: 'User' }, _game : { type: Number, ref: 'Game' }, score: Number }); 

Mongoose的devise方式使得您可以相对轻松地build立关系模型,并根据您在模式中定义的ref填充关系数据。 问题是你需要小心填充。 如果你太多或嵌套你的人口,你会遇到性能瓶颈。

Edit 1方法在很大程度上是正确的,但是您通常不希望根据Number来填充远程ref ,或者将模型的_id设置为Number因为mongo使用它自己的散列机制来pipe理_id ,通常这是隐含_idObjectId 。 示例如下所示:

 var ScoreSchema = new mongoose.Schema({ user : { type: Schema.Types.ObjectId, ref: 'User' }, game : { type: Schema.Types.ObjectId, ref: 'Game' }, score: Number }); 

如果由于某种原因,你需要为你的logging保留一个数字ID,可以考虑把它叫做uid或者与mongo / mongoose内部不冲突的东西。 祝你好运!

当你编辑这篇文章的时候,我认为这样会很好。 至less不错:)

检查mongoose查询人口 。 获取相关数据非常有用。

 var mongoose = require('mongoose'), ObjectId = mongoose.Schema.Types.ObjectId // code, code, code function something(req, res) { var id = req.params.id // test id return Lobby.findOne({_id: new ObjectId(id)}) .populate('_game') .exec(function(error, lobby) { console.log(lobby._game.name); }); } 

首先,你在这里碰到一些好的问题。 Mongoose的优点在于,您可以轻松地将模式连接和绑定到单个集合,并在其他集合中引用它们,从而获得关系型和非关系型数据库的最佳性能。

另外,你不会有_id作为你的一个属性,Mongo会为你添加它。

我使用mongoose.Schema.Types.ObjectIdtypes对模式进行了一些更改。

 var UserSchema = new mongoose.Schema({ username: { type: String, index: true, required: true, unique: true }, email: { type: String, required: true }, password: { type: String, required: true }, scores: [{ type: Schema.Types.ObjectId, ref: 'Score' }] }); var GameSchema = new mongoose.Schema({ name: String }); var LobbySchema = new mongoose.Schema({ _game: { type: mongoose.Schema.Types.ObjectId, ref: 'Game' }, name: String }); var ScoreSchema = new mongoose.Schema({ _user : { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, _game : { type: mongoose.Schema.Types.ObjectId, ref: 'Game' }, score: Number }); 

这将允许您查询您的数据库并填充任何引用的集合和对象。

例如:

 ScoreSchema.find({_id:##userIdHere##}) .populate('_user') .populate('_game') .exec(function(err, foundScore){ if(err){ res.send(err) } else { res.send(foundScore) } } 

这将填充相关的用户和游戏属性。

两种方式(我知道的)。 你存储一个id(索引),一旦你查询第一个表,然后查询第二个表来获取信息,因为没有连接。 这意味着如果从一个表中抓取用户标识,则需要对用户表进行多个查询以获取用户的数据。

另一种方法是将其全部存储在一张表中,即使是重复的。 如果您需要存储的只是一个用户的屏幕名称和其他信息,则只需将其与其他数据一起存储,即使它已经在用户表中。 我相信别人会知道更好/不同的方式。