Modeling email preferences

In my app, a Meteor.user can belong to several Organizations. I’d like to send each user email digests for each organization they belong to at a scheduled time each day.

For additional context, right now I have an organizations field that hangs off Meteor.user(), which I use for a few different .find() queries, and is just an array, e.g.:

organizations: [org1Id, org2Id]

What’s the best way to model this?

Here are a few options that come to mind:

  1. Add the preference to the organization field that hangs off Meteor.user(). So something like
organizations: [
{_id: org1Id, preferences: {morningDigest: true, eveningDigest: false}}, 
{_id: org2Id, preferences: {morningDigest: false, eveningDigest: false}}
]

This would require me to use dot notation syntax to query the preferences. I thought I read somewhere though that using the dot notation syntax had some downsides. It would also require changing some of my existing .find() queries.

  1. An alternate of the above would be to create a new field on Meteor.user(). Something like:
preferences: [{organizationId: org1Id, morningDigest: true, eveningDigest: false}, {organizationId: org2Id, morningDigest: false, eveningDigest: false}]
  1. set up a new Preferences collection where each document would have something like:
_id: 123
userId: userId,
organizationId: organizationId,
morningDigest: true,
eveningDigest: false

Maybe there’s another option that would be even better than the above. Appreciate any insight y’all might be able to offer. :slight_smile:

The fun thing about Mongo is there’s no “Right” way to model your data.

In a relational database, you would separate out an organisations table and an preferences table from your users table like in option 3

Personally, I would go with option 1, and keep the information together with the user.

1 Like
Meteor.user()
{
    organizations: [org1Id, org2Id, ...]    
    .......
    morningDigest: [org1Id, org2Id, ...],
    eveningDigest: [org3Id, org1Id, ...]
}

Now you have to think what is the more efficient way to query and send email. If you can send the same org digest email to many at once, it is better to keep the users on the org and not the org on the user. If that would result in a too large array of users on an org, perhaps, have a collection of digests. With Mongo it is always better to have 10.000 documents in a collection than 10.000 items in an array.
Digests collection:

[
  {_id: xxxx, orgId: yyy, userId: ..rather_optional, userEmail: zzzzz, morning: true},
   /* or for multiple times of the day */
  {_id: xxxx, orgId: yyy, email: zzzzz, batch: 1},
]

then things are very easy:


this.unblock() // email methods should use unblock.
const morning = Digests.find({ morning: true })
const emails = []
morning.map(digest => {
    emails.push(digest.email)
})
Method to send digest to [emails]


1 Like