关系和嵌入式对象 — Node.js SDK
对一关系
对一关系是指在对象模式中,一个对象与不超过一个其他对象相关。要定义对一关系,请将属性类型指定为相关 Realm 对象类型。
例子
应用程序可以使用以下对象模式来指示 Manufacturer
可以制造单台 Car
:
class Manufacturer extends Realm.Object { static schema = { name: "Manufacturer", properties: { _id: "objectId", name: "string", // A manufacturer that may have one car car: "Car?", }, }; } class Car extends Realm.Object { static schema = { name: "Car", properties: { _id: "objectId", model: "string", miles: "int?", }, }; }
class Manufacturer extends Realm.Object { _id!: BSON.ObjectId; name!: string; car?: Car; static schema: ObjectSchema = { name: "Manufacturer", properties: { _id: "objectId", name: "string", // A manufacturer that may have one car car: "Car?", }, }; } class Car extends Realm.Object { _id!: BSON.ObjectId; model!: string; miles?: number; static schema: ObjectSchema = { name: "Car", properties: { _id: "objectId", model: "string", miles: "int?", }, }; }
对多关系
对多关系是指一个对象以特定方式与多个对象相关。要定义对多关系,请指定一个属性,其类型为对象模式中相关 Realm 对象类型的列表或数组。
例子
应用程序可以使用以下对象模式来指示 Manufacturer
可以创建多个 Car
模型:
class Manufacturer extends Realm.Object { static schema = { name: "Manufacturer", properties: { _id: "objectId", name: "string", // A manufacturer that may have many cars cars: "Car[]", }, }; } class Car extends Realm.Object { static schema = { name: "Car", properties: { _id: "objectId", model: "string", miles: "int?", }, }; }
class Manufacturer extends Realm.Object { _id!: BSON.ObjectId; name!: string; cars!: Realm.List<Car>; static schema: ObjectSchema = { name: "Manufacturer", properties: { _id: "objectId", name: "string", // A manufacturer that may have many cars cars: "Car[]", }, }; } class Car extends Realm.Object { _id!: BSON.ObjectId; model!: string; miles?: number; static schema: ObjectSchema = { name: "Car", properties: { _id: "objectId", model: "string", miles: "int?", }, }; }
反向关系
反向关系将对象链接回在定义的对一或对多关系中引用该对象的任何其他对象。默认情况下,关系定义是单向的。您必须在对象模型中明确将属性定义为反向关系。
例如,对多关系“Manufacturer has many Cars”不会自动创建反向关系“Car belongs to Manufacturer”。如果您没有在对象模型中指定反向关系,则需要运行单独的查询来查找制造汽车的制造商。
要定义反向关系,请在对象模型中定义一个 linkingObjects
属性。linkingObjects
指定待反向的关系的对象类型和属性名称。
无法手动设置反向关系属性的值。每当您添加或删除相关对象时,Realm 都会自动更新隐式关系。
例子
应用程序可以使用以下对象模式来表示:
Manufacturer
可以制作许多Car
模型。每个
Car
都应自动链接回制作它的Manufacturer
。
Manufacturer
对象的cars
属性被定义为与Car
对象的 Realm .List的多对多关系。 它包含给定制造商的所有汽车。
Car
对象的 manufacturer
属性会反转此关系。manufacturer
属性会自动更新以引用其 cars
属性中包含 Car
的任何 Manufacturer
对象。
class Manufacturer extends Realm.Object { static schema = { name: "Manufacturer", properties: { _id: "objectId", name: "string", // A manufacturer that may have many cars cars: "Car[]", }, }; } class Car extends Realm.Object { static schema = { name: "Car", properties: { _id: "objectId", model: "string", miles: "int?", manufacturer: { type: "linkingObjects", objectType: "Manufacturer", property: "cars", }, }, }; }
class Manufacturer extends Realm.Object { _id!: BSON.ObjectId; name!: string; cars!: Realm.List<Car>; static schema: ObjectSchema = { name: "Manufacturer", properties: { _id: "objectId", name: "string", // A manufacturer that may have many cars cars: "Car[]", }, }; } class Car extends Realm.Object { _id!: BSON.ObjectId; model!: string; miles?: number; manufacturer!: Realm.Collection<Manufacturer>; static schema: ObjectSchema = { name: "Car", properties: { _id: "objectId", model: "string", miles: "int?", manufacturer: { type: "linkingObjects", objectType: "Manufacturer", property: "cars", }, }, }; }
动态获取反向链接对象
您可以动态检索带有反向关系的对象,而无需在其模式中定义 linkingObjects
类型。删除模式中的 linkingObjects
类型,使模式看起来像标准的多对多关系。当您需要检索链接对象时,请调用 Realm.Object.linkingObjects() 查询。
例子
在以下反向关系示例的延续中,我们从 Car
模式中删除了类型为 'linkingObjects' 的 manufacturer
字段。应用程序开发者创建多个制造商和汽车对象,并且应用程序将新创建的汽车推送到制造商的 cars
字段中。
要查找制造特定汽车对象的制造商,请调用 .linkingObjects()
并将“制造商”类名称和“汽车”字段作为参数传递。
.linkingObjects()
方法返回对象的结果集合,这些对象的属性会反转此关系。在此示例中,只有一家制造商生产 Sentra 车型,因此我们可以预期该制造商将命名为 Nissan。
const carObjects = realm.objects(Car); // Get the Manufacturer who makes the Car const linkedManufacturer = carObjects[0].linkingObjects( "Manufacturer", "cars" )[0]; expect(linkedManufacturer.name).toBe("Nissan");
const carObjects = realm.objects<Car>(Car); // Get the Manufacturer who makes the Car const linkedManufacturer: Manufacturer = carObjects[0].linkingObjects<Manufacturer>("Manufacturer", "cars")[0]; expect(linkedManufacturer.name).toBe("Nissan");
嵌入式对象
嵌入式对象是一种特殊类型的Realm 对象,用于对复杂数据进行建模。 它们还能更自然地映射到MongoDB document model 。 嵌入式对象与关系类似,但提供了额外的约束。
Realm 将每个嵌入式对象视为父对象内的嵌套数据。嵌入式对象继承父对象的生命周期。它不能作为一个独立的 Realm 对象存在。这意味着嵌入式对象无法具备主键。如果嵌入式对象的父对象被删除,Realm 也会自动删除该嵌入式对象。
提示
嵌入式对象类型可重用、可组合
您可以在多个父对象类型中使用相同的嵌入式对象类型。您还可以将对象嵌入到其他嵌入式对象内部。您甚至可以在其自身的定义中将嵌入式对象类型以递归方式引用为一个可选属性。
Realm 对象模型
要指定 Realm 对象模型定义嵌入式对象,请将 embedded
设置为 true
。可以采用与定义关系相同的方式,从父对象类型引用嵌入式对象类型:
class Manufacturer extends Realm.Object { static schema = { name: "Manufacturer", properties: { _id: "objectId", name: "string", cars: "Car[]", // Embed an array of objects warranties: "Warranty[]", }, }; } class Car extends Realm.Object { static schema = { name: "Car", properties: { _id: "objectId", model: "string", miles: "int?", // Embed one object warranty: "Warranty?", }, }; } class Warranty extends Realm.Object { static schema = { name: "Warranty", embedded: true, properties: { name: "string", termLength: "int", cost: "int", }, }; }
class Manufacturer extends Realm.Object { _id!: BSON.ObjectId; name!: string; cars!: Realm.List<Car>; warranties!: Realm.List<Warranty>; static schema: ObjectSchema = { name: "Manufacturer", properties: { _id: "objectId", name: "string", cars: "Car[]", // Embed an array of objects warranties: "Warranty[]", }, }; } class Car extends Realm.Object { _id!: BSON.ObjectId; model!: string; miles?: number; warranty?: Warranty; static schema: ObjectSchema = { name: "Car", properties: { _id: "objectId", model: "string", miles: "int?", // Embed one object warranty: "Warranty?", }, }; } class Warranty extends Realm.Object { name!: string; termLength!: number; cost!: number; static schema: ObjectSchema = { name: "Warranty", embedded: true, properties: { name: "string", termLength: "int", cost: "int", }, }; }
JSON schema
嵌入式对象映射到父类型模式中的嵌入式文档。此行为与常规 Realm 对象不同,后者映射到自己的 MongoDB 集合。
{ "title": "Contact", "bsonType": "object", "required": ["_id"], "properties": { "_id": { "bsonType": "objectId" }, "name": { "bsonType": "string" }, "address": { "title": "Address", "bsonType": "object", "properties": { "street": { "bsonType": "string" }, "city": { "bsonType": "string" }, "country": { "bsonType": "string" }, "postalCode": { "bsonType": "string" } } } } }
{ "title": "Business", "bsonType": "object", "required": ["_id", "name"], "properties": { "_id": { "bsonType": "objectId" }, "name": { "bsonType": "string" }, "addresses": { "bsonType": "array", "items": { "title": "Address", "bsonType": "object", "properties": { "street": { "bsonType": "string" }, "city": { "bsonType": "string" }, "country": { "bsonType": "string" }, "postalCode": { "bsonType": "string" } } } } } }