使用 Device Sync 对数据建模 - Swift SDK
Realm 对象模型
要定义Realm 对象,请从对象派生一个类。 您定义的每个模型都映射到MongoDB Atlas中自己的集合。 在此示例中, Dog
和Person
都将映射到MongoDB Atlas中的单独集合。
class Dog: Object { true) var _id = ObjectId() (primaryKey: var name = "" var age = 0 } class Person: Object { true) var _id = ObjectId() (primaryKey: var name = "" }
JSON schema
当 Atlas App Services 中有相应的模式时,Device Sync 在同步到 Atlas 时会自动将 Realm Swift 数据类型转换为 BSON。 当客户端设备通过 Device Sync 从 App Services 向下同步数据时,SDK 会将 BSON 转换回 Swift 对象。 如果您通过直接访问 MongoDB Atlas 数据而不是使用 Device Sync 来同步数据来查询这些对象,则会获得 BSON 数据类型。 MongoDB 数据访问不会自动映射到 Swift 对象等效项。
{ "title": "Dog", "bsonType": "object", "required": [ "_id" ], "properties": { "_id": { "bsonType": "objectId" }, "name": { "bsonType": "string" }, "age": { "bsonType": "long" } } }
{ "title": "Person", "bsonType": "object", "required": [ "_id" ], "properties": { "_id": { "bsonType": "objectId" }, "name": { "bsonType": "string" } } }
Realm 关系
对一关系
使用上述示例中的对象,考虑Person
可以有一个Dog
的情况。 我们可以向Person
模型添加一个dog
属性,该属性是指向Dog
对象的可选链接。 对一关系必须是可选的。
class Dog: Object { true) var _id = ObjectId() (primaryKey: var name = "" var age = 0 } class Person: Object { true) var _id = ObjectId() (primaryKey: var name = "" // To-one relationship var dog: Dog? }
JSON schema
在 App Services 模式中,我们看到新属性转换为字段dog
。 该字段不在required
数组中,因为它是可选属性。 其类型为objectId
Dog
Dog
,链接到单独的collection集合中的特定对象 。ObjectId 是Dog
模型的主键,因此它是链接两个对象的字段。
{ "title": "Person", "bsonType": "object", "required": [ "_id" ], "properties": { "_id": { "bsonType": "objectId" }, "dog": { "bsonType": "objectId" }, "name": { "bsonType": "string" } } }
Dog
模式保持不变。 由于这是一种对一关系,因此是一种单向关系; Dog
与Person
没有关系。
对多关系
使用上述示例中的对象,考虑一个Person
可以有多个犬的情况。 我们可以将一个dogs
属性添加到Person
模型中,该模型是Dog
对象的列表。 如果此人没有狗,则这是一个空列表。 当此人养狗时,我们可以创建新的狗对象并将它们附加到此人的dogs
列表中。
class Dog: Object { true) var _id = ObjectId() (primaryKey: var name = "" var age = 0 } class Person: Object { true) var _id = ObjectId() (primaryKey: var name = "" // To-many relationship - a person can have many dogs var dogs: List<Dog> }
JSON schema
在 App Services 模式中,我们看到新属性转换为字段dogs
。 该字段的类型是数组,数组中项目的类型为objectId
。 这是因为我们将Dog
模型上的主键定义为objectId
。 该字段是与Dog
Person
对象相关的所有 对象的主键数组。
{ "title": "Person", "bsonType": "object", "required": [ "_id" ], "properties": { "_id": { "bsonType": "objectId" }, "name": { "bsonType": "string" }, "dogs": { "bsonType": "array", "items": { "bsonType": "objectId" } } } }
反向关系
使用上述示例中的对象,考虑Dog
对象与Person
对象具有反向关系的情况。
class Dog: Object { true) var _id = ObjectId() (primaryKey: var name = "" var age = 0 // The backlink to the `Person` who has this `Dog`. "dogs") var person: LinkingObjects<Person> (originProperty: } class Person: Object { true) var _id = ObjectId() (primaryKey: var name = "" // To-many relationship - a person can have many dogs var dogs: List<Dog> }
JSON schema
在 App Services 模式中,我们发现表示与Dog
模型中的Person
反向关系的person
属性不存在。 您不能直接设置反向关系的值,并且 Atlas 中不存在该关系。 但是,Realm 会根据您的 Realm 对象模型在客户端应用程序中为您派生并更新这些关系。
{ "title": "Dog", "bsonType": "object", "required": [ "_id" ], "properties": { "_id": { "bsonType": "objectId" }, "name": { "bsonType": "string" }, "age": { "bsonType": "long" } } }
嵌入式对象模型
当您使用 Realm Swift SDK 定义嵌入式对象时,您会从EmbeddedObject派生一个类。 您可以像定义关系一样从父对象类型引用嵌入式对象类型:
class Person: Object { true) var id = 0 (primaryKey: var name = "" // To-many relationship - a person can have many dogs var dogs: List<Dog> // Inverse relationship - a person can be a member of many clubs "members") var clubs: LinkingObjects<DogClub> (originProperty: // Embed a single object. // Embedded object properties must be marked optional. var address: Address? convenience init(name: String, address: Address) { self.init() self.name = name self.address = address } } class DogClub: Object { var name = "" var members: List<Person> // DogClub has an array of regional office addresses. // These are embedded objects. var regionalOfficeAddresses: List<Address> convenience init(name: String, addresses: [Address]) { self.init() self.name = name self.regionalOfficeAddresses.append(objectsIn: addresses) } } class Address: EmbeddedObject { var street: String? var city: String? var country: String? var postalCode: String? }
JSON schema
嵌入式对象映射到父类型模式中的嵌入式文档。此行为与常规 Realm 对象不同,后者映射到自己的 MongoDB 集合。
{ "title": "Person", "bsonType": "object", "required": ["id"], "properties": { "id": { "bsonType": "int" }, "name": { "bsonType": "string" }, "dogs": { "bsonType": "array", "items": { "bsonType": "objectId" } }, "address": { "title": "Address", "bsonType": "object", "properties": { "street": { "bsonType": "string" }, "city": { "bsonType": "string" }, "country": { "bsonType": "string" }, "postalCode": { "bsonType": "string" } } } } }
{ "title": "DogClub", "bsonType": "object", "required": ["_id", "name", "addresses"], "properties": { "_id": "objectId", "name": { "bsonType": "string" }, "members": { "bsonType": "array", "items": { "bsonType": "objectId" } }, "addresses": { "bsonType": "array", "items": { "title": "Address", "bsonType": "object", "properties": { "street": { "bsonType": "string" }, "city": { "bsonType": "string" }, "country": { "bsonType": "string" }, "postalCode": { "bsonType": "string" } } } } } }
创建对象模型和模式
要在Atlas中的 SDK对象模型和BSON数据之间进行映射,您必须在App Services 模式中具有与您的SDK对象模型相匹配的模式。 有几种方法可以生成匹配的模式和对象模型:
在客户端应用程序中创建对象模型,并从中生成 App Services 模式。
在 App Services 中创建模式,并从中生成 Realm 对象模型。
如果正在开发新的客户端应用程序,您可能希望迭代客户端应用程序中的数据模型。 在 中启用 开发模式 ,让后端根据客户端对象模型推断和更新模式。Atlas App Services开发模式不适用于重大模式更改,因此对 SDK 数据模型进行重大更改时,必须从服务器中删除现有模式。
如果您正在开发一个客户端应用程序,并且该应用程序需要处理Atlas中已存在的数据,则可以根据该数据生成模式。 然后,您可以从服务器端模式生成 SDK对象模型。