MongoDB Realm partition strategy for a chat app

I wanted to enquire as to how to partion my chat data into realms in mongoDB realm. Users can be part of of any number of chatrooms.

Right now my chat database has _partition as the partitionValue, and the following collections-

export const chatroomSchema = {
  name: 'chatroom',
  properties: {
    _id: 'objectId',
    _partition: 'string?',
    date: 'date',
    last_message: 'string',
    title: 'string',
  },
  primaryKey: '_id',
};

export const userSchema = {
  name: 'user',
  properties: {
    _id: 'objectId',
    _partition: 'string?',
    chatrooms: 'chatroom[]',
    friends: 'user[]',
    name: 'string',
    photoUrl: 'string',
    username: 'string',
  },
  primaryKey: '_id',
};

export const messageSchema = {
  name: 'message',
  properties: {
    _id: 'objectId',
    _partition: 'string?',
    content: 'string',
    chatroom_id: 'string',
    date: 'date',
    sender: 'user?',
  },
  primaryKey: '_id',
};

export const memberSchema = {
  name: 'member',
  properties: {
    _id: 'objectId?',
    _partition: 'string?',
    chatroom_id: 'string?',
    participants: 'user[]',
  },
  primaryKey: '_id',
};

Thank You In Advance. Stay Safe!

@Aryaman_Shrey So chat applications are pretty complex but one approach I have seen is to have a partition per chat room. Generally you only want to hold about 10 partitions open at any one time for a mobile app. I’m not sure how many chatRooms you are expecting a user to join but what you can do to get around this limitation is to have a per-user notification partition which would contain a list of potential chatRooms the user could join as well as a Notification object which would say that you have a chat message pending from a chatRoom the user had joined which was closed on the mobile at that time since realm only syncs when the realm reference is active. You would use Realm Database trigger to detect that a new message was pending on the backend and insert a new Notification object into the per-user notification realm which contained a partitionKey value for the chatRoom where the message was pending.

Sorry for the intrusion on this thread, but I am also writing a chat program for MongoDB Realm. I agree with @Ian_Ward that each chat should be given their realm. This is both more scalable, but more importantly more secure as only members of the chat can access the chat Realm. The question I have is one of scalability on writes. I have read somewhere that MongoDB Realm (or maybe the older Realm Cloud) could only support up to 30 concurrent users writing to the same Realm at the same time. To mitigate this scalability issue, we were thinking of have each user write the chat data to their private realm, and having a backend server function copy it to the chat’s shared realm, which would only be read-only to the various members of the chat. I would welcome any feedback.

@Richard_Krueger That’s correct - the old Realm system would start to slow down around 30 writers per realm because it would tax the conflict resolution algorithm. We don’t know what the performance will be with the new MongoDB Realm because we haven’t done granular performance testing yet but that is on deck this quarter and we expect it to be much higher in the new system since we are now leveraging MongoDB for storage.

Your proposal of moving chats to different realms with a server side function is a fair workaround.

But does not multiple realms create a whole number of other complexities like querying across realms?

@Anthony_CJ I don’t think that you would want to query across multiple realms. Usually you already know which realm the object is in before the query.

I would instead take a look at Flexible Sync as this makes it much easier to implement a chat style application without the copying of data between partitions with triggers that Partition-based Sync required. I would take a look at @Andrew_Morgan 's post on how he built RChat here -

This will actually get much simpler as we are looking to release queries on arrays hopefully next week!