Each Parse class is a MongoDB collection; each object, a document. Good models come from the screens you'll build: model for how you read the data, not only for how you store it.
Field types
| Type | For |
|---|---|
| String, Number, Boolean, Date | Plain values |
| Object, Array | Nested JSON: small, read together with the object |
| Pointer | A reference to one other object |
| Relation | A many-to-many link, stored apart from the object |
| File | An uploaded file |
| GeoPoint | A location, for "near me" queries |
| ACL | Who may read and write the object |
Define the schema in Core › Browser (or with the API) rather than letting clients create fields, and keep Add field off for clients (Secure your app).
Linking objects
| Pointer | Array of pointers | Relation | |
|---|---|---|---|
| Shape | One-to-one, many-to-one | One-to-few | Many-to-many, many-to-lots |
| Example | A comment's post |
A post's 3 tags |
A user's followers |
| Read with the object | include('post'), same request |
include('tags') |
A separate query |
| Size | 1 | Keep it small (tens) | Unbounded |
const comment = new Parse.Object('Comment', { text: 'Nice!', post });
await comment.save();
// comments of a post, with the post itself in one request
const comments = await new Parse.Query('Comment')
.equalTo('post', post)
.include('post')
.descending('createdAt')
.limit(20)
.find();
Prefer a pointer from the "many" side (the comment points to its post) over an array on the "one" side: it grows without limit, and it queries and indexes well.
Denormalize what you show often
Reading related objects on every screen costs requests. Copy what you need where you read it:
- a
commentCounton the post, kept up to date in anafterSaveofComment; - the author's name next to the author pointer, if lists show it;
- the latest message's text on the conversation.
Copies get stale, so update them in cloud code, not from clients.
Model for permissions
Permissions apply per class and per object, so split data by who may see it:
- public profile fields in a
Profileclass readable by everyone; email and settings stay in_User, readable only by the user; - one object per owner, with the owner's ACL, rather than a shared object that everyone updates.
Model for speed
- Query by fields you can index, and sort by them.
- Avoid huge objects: big arrays and nested objects are read and rewritten in full on every save.
- Keep large data (images, documents, exports) in files, not in fields.
Parse's JavaScript guide covers every relation API in detail.