I am about to build my node.js / express / mongoose / passport application and I am thinking about the right schema design for users and accounts.
There will be users loging in from twitter and facebook as well as from native accounts. At a later stage I want a user to connect both twitter and facebook with my application (and maybe even more external accounts).
I can not think of a good solution for that situation. Here are the options I am thinking of:
1.Having a profile model and account models. Profile documents represent the unique user, while an account provides either username and password (internal account) or the authentication data from the auth-provider (external account). A profile has to have at least one nested account document.
var ExtAccountSchema = new Schema({
type: String, // eg. twitter, facebook, native
uid: String
});
var IntAccountSchema = new Schema({
username: String,
password: String
});
var ProfileSchema = new Schema({
firstname: String,
lastname: String,
email: String,
accounts: [Account] // Pushing all the accounts in there
});
What I dislike about it are the not so consistent account documents resulting from different account data and the fact that I have a hard time finding the right account when my user logs in (searching uids and account types in nested documents -.-)
2.Having all data in a single model
var ProfileSchema = new Schema({
firstname: String,
lastname: String,
email: String,
twitter-uid: String,
facebook-uid: String
password: String
});
Well this is just ugly -.- It might be easier/faster to find the right account data but it’s not nice to maintain.
Is there a better solution? Is there a best practice?
1) There are three strategies that you might take to structure your data in MongoDB:
Strategy (a) is the first one you describe, where the Profile document contains an array of Account sub-documents.
Strategy (b) is similar to strategy (a), but you’d use an array of references to other documents (typically in an Account collection) rather than embedding the actual documents.
Strategy (c) is the one you describe as “having all data in a single model”.
2) It’s generally considered Best Practice to use an array of embedded documents, especially if the information in them can vary. If it will make your life easier, you can use a key to distinguish the type of the account, like so:
3) MongoDB allows you search on an embedded document. So you would write the following query (JavaScript syntax):
With appropriate indexes, this query will be quite fast.