Embedded Objects¶
Overview¶
An embedded object is a special type of Realm object that models complex data about a specific object. Embedded objects are similar to relationships, but they provide additional constraints and map more naturally to the denormalized MongoDB document model.
Realm enforces unique ownership constraints that treat each embedded object as nested data inside of a single, specific parent object. An embedded object inherits the lifecycle of its parent object and cannot exist as an independent Realm object. Realm automatically deletes embedded objects if their parent object is deleted or if they are overwritten by a new embedded object.
When you delete a Realm object, Realm automatically deletes any embedded objects referenced by that object. Any objects that your application must persist after the deletion of their parent object should use relationships instead.
Embedded Object Data Models¶
You can define embedded object types using either Realm object models or a server-side document schema. Embedded object types are reusable and composable. You can use the same embedded object type in multiple parent object types and you can embed objects inside of other embedded objects. You can even recursively reference an embedded object type as an optional property in its own definition.
Embedded objects cannot have a primary key.
Realm Object Models¶
To specify that a Realm object model define an embedded object, set embedded
to true
. You can reference an embedded object type from parent object types
in the same way as you would define a relationship:
const AddressSchema = { name: "Address", embedded: true, // default: false properties: { street: "string?", city: "string?", country: "string?", postalCode: "string?", }, }; const ContactSchema = { name: "Contact", primaryKey: "_id", properties: { _id: "objectId", name: "string", address: "Address", // Embed a single object }, }; const BusinessSchema = { name: "Business", primaryKey: "_id", properties: { _id: "objectId", name: "string", addresses: { type: "list", objectType: "Address" }, // Embed an array of objects }, };
JSON Schema¶
Unlike regular Realm objects, which map to their own MongoDB collection, embedded objects map to embedded documents in the parent type's document schema:
{ "title": "Contact", "bsonType": "object", "required": ["_id"], "properties": { "_id": "objectId", "name": "string", "address": { "title": "Address", "bsonType": "object", "properties": { "street": "string", "city": "string", "country": "string", "postalCode": "string" } } } }
{ "title": "Business", "bsonType": "object", "required": ["_id", "name", "addresses"], "properties": { "_id": "objectId", "name": "string", "addresses": { "bsonType": "array", "items": { "title": "Address", "bsonType": "object", "properties": { "street": "string", "city": "string", "country": "string", "postalCode": "string" } } } } }
Read and Write Embedded Objects¶
Create an Embedded Object¶
To create an embedded object, specify it as a nested object when you define the parent object:
realm.write(() => { realm.create("Contact", { _id: new BSON.ObjectId(), name: "Freddy Krueger", address: { street: "Elm Street", city: "Springwood", }, }); });
Update an Embedded Object Property¶
To update a property in an embedded object, modify the property in a write transaction using dot-notation:
realm.write(() => { const contact = realm.objectForPrimaryKey("Contact", "5f0f302824ec9735fe19ecf8"); contact.address.city = "New York City"; const business = realm.objectForPrimaryKey("Business", "5f345ceaafbcc6c8e91bf2c3"); business.addresses.push({ city: "New York City", street: "1 Wall Street" }); business.addresses[0].city = "Boston"; });
Overwrite an Embedded Object¶
To overwrite an embedded object, set the value of the embedded object property to a new object in a write transaction:
realm.write(() => { const contact = realm.objectForPrimaryKey("Contact", "5f0f302824ec9735fe19ecf8"); contact.address = { city: "Chicago", street: "1800 N Clark Street" }; const business = realm.objectForPrimaryKey("Business", "5f345ceaafbcc6c8e91bf2c3"); // Overwrite a specific object in the list business.addresses[0] = { city: "Chicago", street: "2100 N Clark Street" }; // Overwrite the entire list business.addresses = [ { city: "Chicago", street: "2100 N Clark Street" }, { city: "Indianapolis", street: "123 W Washington Street" }, ] });
Query a Collection on Embedded Object Properties¶
Use dot-notation to filter or sort a collection of objects based on an embedded object property value:
It is not possible to query embedded objects directly. Instead, access embedded objects through a query for the parent object type.
const nycContacts = realm.objects("Contact") .filtered("address.city = 'New York City'") .sorted("address.street");