Is this an efficient way of storing notifications with MongoDB. I want to keep track of past notifications and if the notification has been read by the user.
NotificationSchema: {
title: {type: String, required: true},
context: {type: String, required: true},
createdAt: {type: Date, default: Date.now(), required: true},
readBy: [
userObjectID: {type: mongoose.Schema.Types.ObjectId, required: true},
readAt: {type: Date, required: true, default: Date.now()}
]
}
My worry is that when the list gets big, each user would have to go through the entire "readBy" field in order to determine if the user has read it.
Should I also store within the UserSchema, a field to record all notifications read by the user?
Thank you! Any input is appreciated.
CodePudding user response:
You may consider to create an additional intermediate model like UserNotification, and remove the readBy array field from Notification.
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const NotificationSchema = new Schema({
title: { type: String, required: true },
context: { type: String, required: true },
createdAt: { type: Date, default: Date.now(), required: true }
});
const UserSchema = new Schema({
username: { type: String, required: true }
});
const UserNotificationSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: "User"
},
notification: {
type: Schema.Types.ObjectId,
ref: "Notification"
},
readAt: { type: Date, required: true, default: Date.now() }
});
module.exports = {
Notification: mongoose.model("Notification", NotificationSchema),
User: mongoose.model("User", UserSchema),
UserNotification: mongoose.model("UserNotification", UserNotificationSchema)
};
With this design, adding a UserNotification requires only a simple insert into only one collection, and our Notification and User schema is not polluted.
But we need to setup virtual populate on the Notification and User schemas to be able to reference UserNotification. You can check this answer for an example how to setup virtual populate.