I was wondering what is the best scheme for user/notifications kind of scenario like the following :
Embedded notifications scheme
Notifications = new Schema ( {
message : String,
date : { type : Date, default: Date.now() }
read : { type: Boolean, default : false }
});
User = new Schema( {
username : String,
name : String,
notifications : [Notifications]
});
Pros :
Cons :
Populate (DBRef like) objects
Notification = new Schema ({
message : String,
date : { type : Date, default : Date.now() }
});
UserNotification = new Schema ({
user : { type : Schema.ObjectId, ref : 'User' },
notification : { type : Schema.ObjectId, ref : 'Notification' },
read : { type : Boolean, default : false }
});
User = new Schema( {
username : String,
name : String,
notifications : [ { type : Schema.ObjectID, ref : 'UserNotification' } ]
});
Pros :
Cons :
Thank you, in advance and I'm sorry for the long post, but I think I can't explain it simpler.
Option 1 looks like it will probably result in a lot of excessive document growth and moves, which would be bad for performance, since most of your writes will be going to the embedded doc (Notifications).
Option 2 I'm not totally clear on your strategy - it seems redundant to have those 3 collections but also embed a list of notifications by objectId if you are already referencing user by ID in the notifications table. You could index on user in Notifications table, and then eliminate the nested array in the Users table.
(EDIT) Here's another strategy to consider.
Three collections that look like this:
Users:
_id: objectid
username : string
name: string
Notifications:
_id: objectid
to (indexed): objectid referencing _id in "users" collection
read: boolean
Global Notifications:
_id: objectid
read_by: [objectid referencing _id in users]
For notifications meant for a single user, insert into Notifications for that user. For multiple users, insert one for each user (alternately, you could make the "to" field an array and store _ids of all the recipients, and then maintain another list of all the recipients who have read it). To send a notification to all users, insert into Global Notifications collection. When the user reads it, add their user's _id to the read_by field. So, to get a list of all the unread notifications of a user, you do two queries: one to notifications, and one to global notifications.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With