Asking for Schema Design Advice for Realm Sync

Hi,

Good day,
Would like to ask for some advice regarding the data modelling along with partition strategies.

User:

  • Represents an user from a group
  • realmId/partition will be the groupId for separation of data among groups
{
	"title": "User",
	"bsonType": "object",
	"required": ["realmId", "_id", "email", "username", "firstName", "lastName"],
	"properties": {
		"realmId": {"bsonType": "string"},
		"_id": {"bsonType": "string"},
		"email": {"bsonType": "string"},
		"username": {"bsonType": "string"},
		"firstName": {"bsonType": "string"},
		"lastName": {"bsonType": "string"}
	}
}

Project:

  • A project created by user from a group and able to invite other user from different group to collaborate as well
  • realmId/partition will be set to groupId of the project’s creator so that we don’t put project in public realm
  • Project could also includes a lot of embedded documents which is not shown here for brevity
  • As to how we can add user from other group? We have GroupToRealmMapping to query user from another group
{
	"title": "Project",
	"bsonType": "object",
	"required": ["realmId", "_id", "projectName", "startDate", "endDate"],
	"properties": {
		"realmId": {"bsonType": "string"}
		"_id": {"bsonType": "string"},
		"projectName": {"bsonType": "string"},
		"startDate": {"bsonType": "date" },
		"endDate": {"bsonType": "date" },
		"assignees": {
			  "bsonType": "array",
			  "uniqueItems": true,
			  "items": {
				"bsonType": "string"
			}
		},
	}
}

GroupToRealmMapping:

  • Resides in global/public realm
  • A mapping from group to realm with groupId as the primary key
  • only to discover users from another group by opening another realm
{
	"title": "GroupToRealmMapping",
	"bsonType": "object",
	"required": ["realmId", "_id"],
	"properties": {
		"_id": {"bsonType": "string"}
		"realmId": {"bsonType": "string"}
	}
}

ProjectMeta

  • Resides in global/public realm
  • ProjectMeta will be created whenever a new project is created regardless of group
  • For discovery of projects from all the groups, mainly for administration purposes
  • Also act as proxy to access the actual project that resides in another realm
  • eg: project rendered as card with basic information before actually opening up the associated realm with filter(projectId) for actual project that comes with lots of payloads
{
	"title": "ProjectMeta",
	"bsonType": "object",
	"required": ["realmId", "_id", "projectName", "startDate", "endDate" ],
	"properties": {
		"realmId": {"bsonType": "string"}
		"projectRealmId": {"bsonType": "string"}
		"_id": {"bsonType": "string"},
		"projectName": {"bsonType": "string"},
		"startDate": {"bsonType": "date" },
		"endDate": {"bsonType": "date" },
		"assignees": {
			  "bsonType": "array",
			  "uniqueItems": true,
			  "items": {
				"bsonType": "string"
			}
		},
	}
}

UserToProjectMetasMapping:

  • Resides in global/public realm
  • As we can join as collaborator in project created by other group; however, the project will not be available in our realm
  • Thus, this will act like a mapping to all the projects we are involving in
  • Similar to the GroupToRealmMapping but in smaller and private scale
  • eg: the ProjectMeta(s) can be populated as cards in user’s page while serving as a gateway to the actual realm that the project resides upon opening
{
	"title": "UserToProjectMetasMapping",
	"bsonType": "object",
	"required": ["realmId", "_id"],
	"properties": {
		"_id": {"bsonType": "string"}
		"realmId": {"bsonType": "string"}
		"projectMetas": {
			  "bsonType": "array",
			  "uniqueItems": true,
			  "items": {
				"bsonType": "string"
			}
		},
	}
}

Questions:

  1. There seem to be a lot of indirection needed to access the data I want due to the fact that they resides in different realms; how could I improve it?
  2. Is my understanding even correct?
  3. Do we sync all the data in a realm to disk or it is depending on how we access the data? eg: We open one project in the realm and only that one gets synced locally; is this statement true?

Thanks,
Vincent

Hi @VincentTan - welcome to the community!

Regarding 1 & 2, I think this seems a decent approach. A certain amount of indirection/duplication is often needed because of the way that partitioned sync works.

Have you come up with the sync permissions to go along with this schema?

You will probably need to encode a key-value pair within the realmId string so that your permission-checking function can get the context of what needs to be checked from the key, and the value to check from the value. e.g., realmId: "groupId=27391269".

Have you taken a look at this post which may help… Realm Partitioning Strategies | MongoDB

2 Likes

For question 3 – the whole partition will be stored on the device

1 Like

Hi Andrew,

Thanks for your help.
I haven’t looked into permission yet but will look into it soon.
Will post a query in the community if I have any question regarding that topic.

Thanks,
Vincent

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.