使用 Device Sync 对数据建模 - Kotlin SDK
在此页面上
本页介绍 Device Sync Realm 数据模型,以及如何使用该模型将数据从 Device Sync 使用的 App Services 模式映射到客户端中 Kotlin SDK 使用的 Realm 模式。
此页面不会:
解释如何在客户端应用中定义 Realm 对象模型。 要了解如何操作,请参阅定义 Realm 对象模型 - Kotlin SDK。
解释如何在客户端应用程序上设置 Device Sync。 要了解如何操作,请参阅将Device Sync 添加到应用 - Kotlin SDK。
有关Device Sync的详细说明,请参阅Atlas App Services文档中的 Atlas Device Sync入门。
提示
定义 Device Sync 数据模型
Atlas Device Sync Realm 数据模型由以下模式定义,允许 Device Sync 在客户端和 Atlas 之间映射数据:
Realm 模式:应用中的客户端对象模型,它使用 Kotlin SDK 将数据定义为 Kotlin 类。
App Services 模式 : Atlas App Services中的服务器端模式,用于定义BSON格式的数据。 有关更多信息,请参阅App Services文档中的模式。
在同步数据时,Device Sync 使用这些模式来验证对象并在 Kotlin 和 BSON 格式之间转换对象。 当您从客户端同步数据时,Device Sync 会自动将 Realm Kotlin 数据类型转换为 BSON。 然后,当客户端设备通过 Device Sync 从 Atlas 同步数据时,SDK 会将 BSON 数据转换回 Kotlin 对象。
要使用 Device Sync,必须定义 Realm 模式和 App Services 模式,并且这两个模式必须一致。
您可以先在客户端应用程序或 Atlas 中定义模式,具体取决于您的偏好和使用案例。 然后,您可以使用匹配的对象模型生成相应的模式。
从客户端应用程序生成模式
如果正在开发新的客户端应用程序,您可能希望迭代客户端应用程序中的数据模型。 直接在客户端应用代码中定义对象模型后,可以在 App Services 中启用开发模式以自动生成匹配的 App Services 模式。
开发模式是一种配置设置,当您从客户端同步数据时,允许Device Sync根据客户端数据模型推断和更新模式。 有关更多信息,请参阅App Services文档中的开发模式。
使用现有 Atlas 数据生成模式
如果您正在开发一个客户端应用程序,该应用程序需要处理Atlas中已存在的数据,则可以从该数据生成模式,然后生成要在Kotlin客户端应用中使用的 SDK对象模型。 要学习;了解更多信息,请参阅App Services文档中的使用客户端应用程序同步Atlas中的数据。
Device Sync 要求
要成功同步对象,有一些要求。 如前所述,您必须具有匹配的 Realm 和 App Services 模式,其中包含要同步的对象。
此外,Device Sync 要求:
Realm 对象映射
Realm 对象是 Realm 模式中定义的 Kotlin 类的唯一命名实例,用于确定该类型对象的属性和关系。
App Services 通过以下方式将 Realm 对象映射到 Atlas:
Realm 对象名称映射到链接的 Device Sync 数据源中的 Atlas collection。请注意以下事项:
当开发模式启用时,App Services 会自动为您同步的每个新 Realm 对象类型创建 collection 和模式。
嵌入式对象不会存储在Atlas中自己的集合中。 这是因为它们不能存在于其父对象类型之外。 有关更多信息,请参阅本页的嵌入式对象部分。
Realm 对象模式映射到相应的 collection 中的 App Services 模式。
在以下示例中, Frog
和Pond
对象的基本属性在 Realm 模式中定义:
// Maps to `Frog` collection class Frog : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" var age: Int? = null } // Maps to `Pond` collection class Pond : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" }
在 Atlas 中,我们可以看到这些 Realm 对象类型如何映射到相应的 App Services 模式——每个对象都映射到各自的 collection。我们还看到了符合此Realm 数据模型的青蛙和池塘对象的示例:
{ "title": "Frog", "type": "object", "required": [ "_id", "name" ], "properties": { "_id": { "bsonType": "objectId" }, "age": { "bsonType": "long" }, "name": { "bsonType": "string" } } }
{ "title": "Pond", "type": "object", "required": [ "_id", "name" ], "properties": { "_id": { "bsonType": "objectId" }, "name": { "bsonType": "string" } } }
{ "_id": ObjectId("5af712eff26b29dc5c51c60f"), "name": "Kermit", "age": 42 }
{ "_id": ObjectId("5af714eff24b294c5251cf04"), "name": "Kermit's Pond" }
Realm 关系映射
您的 Realm 对象模型可能包括对象之间的关系。 主要有两种类型的关系:
一对一关系:一个对象以特定方式与不超过一个其他 Realm 对象相关。
对多关系:一个对象以特定方式与多个 Realm 对象相关。
关系由引用其他 Realm 对象主键的属性映射。
有关在Atlas App Services 模式中进行关系建模的更多信息,请参阅 Atlas App Services文档中的 关系 。
映射对一关系
一对一关系将一个属性映射到另一个 Realm 对象的单个实例。 对一关系必须是可选的。 有关如何在 Kotlin SDK 中定义对一关系的更多信息,请参阅定义对一关系属性。
使用上例中的对象,考虑Frog
可以有一个最喜欢的池塘的情况。 我们可以向Frog
模型添加一个favoritePond
属性,该属性是指向Pond
对象的可选链接。
class Frog : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" var age: Int? = null // To-one relationship (MUST be optional) var favoritePond: Pond? = null }
在 App Services 模式中,我们看到新属性转换为字段favoritePond
:
该字段不在
required
数组中,因为它是可选属性。其类型是一个
objectId
Pond
Pond
,链接到单独的collection中的特定对象。这是因为我们将Pond
模型上的主键定义为objectId
。
Pond
模式保持不变。 由于这是一种对一关系,因此是一种单向关系; Pond
与Frog
没有关系。
{ "title": "Frog", "type": "object", "required": [ "_id", "name" ], "properties": { "_id": { "bsonType": "objectId" }, "age": { "bsonType": "long" }, "favoritePond": { "bsonType": "objectId" }, "name": { "bsonType": "string" } } }
对多关系
对多关系将一个属性映射到另一个 Realm 对象的零个或多个实例。 有关如何在 Kotlin SDK 中定义对多关系的更多信息,请参阅定义对多关系属性。
考虑另一种情况,其中Frog
可以有许多而不是一个最喜欢的池塘。 我们将一个favoritePonds
属性添加到Frog
模型中,该模型是Pond
对象的列表。 如果青蛙没有最喜欢的池塘,则这是一个空列表。 当青蛙喜欢上池塘时,我们可以创建新的Pond
对象并将它们附加到青蛙的favoritePonds
列表中。
class Frog : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" var age: Int? = null // To-many relationship (can have many ponds) var favoritePonds: RealmList<Pond> = realmListOf() }
在 App Services 模式中,我们看到新属性转换为favoritePonds
字段,其中包含与 Frog
对象相关的所有Pond
对象:
该字段不在
required
数组中,因为它是可选属性。此字段的类型是
objectId
类型的数组。这是因为我们将Pond
模型上的主键定义为objectId
。
同样, Pond
模式不会更改,因为Pond
与Frog
没有关系。
{ "title": "Frog", "type": "object", "required": [ "_id", "name" ], "properties": { "_id": { "bsonType": "objectId" }, "age": { "bsonType": "long" }, "favoritePonds": { "bsonType": "array", "items": { "bsonType": "objectId" } }, "name": { "bsonType": "string" } } }
反向关系
反向关系将对象链接回在定义的对一或对多关系(称为反向链接)中引用该对象的任何其他对象。 有关 Kotlin SDK 中如何定义反向关系的更多信息,请参阅定义反向关系。
App Services 模式不支持反向关系。 这是因为反向关系表示 Realm 中的一种隐式关系,会在修改反向链接时自动更新。 这意味着您无法直接设置反向关系的值,并且 Atlas 中不存在该关系。 相反,Realm 会根据您的 Realm 对象模型在客户端应用程序中为您派生并更新这些关系。
考虑Pond
对象与Frog
对象具有反向关系的情况。
class Pond : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" // Backlink to the `Frog` that has this `Pond` as its favorite val frog: RealmResults<Frog> by backlinks(Frog::favoritePonds) } class Frog : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" var age: Int? = null // To-many relationship (can have many ponds) var favoritePonds: RealmList<Pond> = realmListOf() }
在 App Services 模式中,我们通过favoritePonds
属性看到Frog
与Pond
具有多对多关系。 但是,表示与Pond
模型中的Frog
反向关系的frog
属性不存在。 这是因为在 Atlas 中无法显式定义反向关系。 但是,每当您在关系中添加或删除对象时,Realm 都会自动更新它。
// `Pond` schema in App Services DOES NOT contain the // `frog` inverse relationship property { "title": "Pond", "type": "object", "required": [ "_id", "name" ], "properties": { "_id": { "bsonType": "objectId" }, "name": { "bsonType": "string" } } } { "title": "Frog", "type": "object", "required": [ "_id", "name" ], "properties": { "_id": { "bsonType": "objectId" }, "age": { "bsonType": "long" }, "favoritePonds": { "bsonType": "array", "items": { "bsonType": "objectId" } }, "name": { "bsonType": "string" } } }
嵌入式对象
嵌入式对象表示单个特定父对象内部的嵌套数据。 您可以采用与定义关系相同的方式从父Realm 对象类型引用嵌入式对象类型。有关如何在 Kotlin SDK 中定义嵌入式对象的更多信息,请参阅定义嵌入式对象。
但是,与常规 Realm 对象不同,嵌入式对象不会存储在 Atlas 中自己的 collection 中。相反,它们存储为父对象文档的一部分,并且无法在父对象之外进行访问。
在以下示例中,我们有一个带有favoritePond
属性的Frog
对象,该属性引用单个嵌入式Pond
对象,还有一个带有forestPonds
关系属性的Forest
对象,该对象引用许多嵌入式Pond
对象的列表:
class Frog : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" var age: Int? = null // Embed a single object (MUST be optional) var favoritePond: EmbeddedPond? = null } class Forest : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" // Embed multiple objects (can have many ponds) var forestPonds: RealmList<EmbeddedPond> = realmListOf() } class EmbeddedPond : EmbeddedRealmObject { var name: String? = null }
在 App Services 模式中,我们看到嵌入式对象映射到每个父类型中的文档:
{ "title": "Frog", "type": "object", "required": [ "_id", "name" ], "properties": { "_id": { "bsonType": "objectId" }, "age": { "bsonType": "long" }, "favoritePond": { "title": "EmbeddedPond", "type": "object", "required": [], "properties": { "name": { "bsonType": "string" } } }, "name": { "bsonType": "string" } } } { "title": "Forest", "type": "object", "required": [ "_id", "name" ], "properties": { "_id": { "bsonType": "objectId" }, "forestPonds": { "bsonType": "array", "items": { "title": "EmbeddedPond", "type": "object", "required": [], "properties": { "name": { "bsonType": "string" } } } }, "name": { "bsonType": "string" } } }
模式类型映射列表
下表演示了Realm对象类型如何映射到相应的Atlas App Services模式BSON类型。 有关支持的Atlas App Services 模式类型及其映射和可用属性的完整列表,请参阅 Atlas App Services文档中的 数据模型映射 。
Kotlin 类型
下表列出了支持的 Kotlin 数据类型,以及声明的属性如何在 Realm 模式和 App Services 模式之间映射的示例。
有关 Kotlin SDK 支持的 Kotlin 数据类型以及如何在 Realm 数据模型中定义这些数据类型的更多信息,请参阅Kotlin 数据类型。
Kotlin 数据类型 | Realm 对象 | 应用程序服务模型 | ||||
---|---|---|---|---|---|---|
String |
|
| ||||
Byte |
|
| ||||
Short |
|
| ||||
Int |
|
| ||||
Long |
|
| ||||
Float |
|
| ||||
Double |
|
| ||||
Boolean |
|
| ||||
Char |
|
|
BSON类型
下表列出了支持的 MongoDB BSON 数据类型,以及声明的属性如何在 Realm 模式和 App Services 模式之间映射的示例。
有关 Kotlin SDK 支持的 MongoDB BSON 数据类型以及如何在 Realm 数据模型中定义这些数据类型的更多信息,请参阅Kotlin 数据类型。
MongoDB BSON 类型 | Realm 对象 | 应用程序服务模型 | ||||
---|---|---|---|---|---|---|
|
| |||||
Decimal128 |
|
|
Realm 类型
下表列出了支持的 Realm 特定数据类型,以及声明的属性如何在 Realm 模式和 App Services 模式之间映射的示例。
有关 Kotlin SDK 支持的 Realm 特定数据类型以及如何在数据模型中定义这些数据类型的更多信息,请参阅Kotlin 数据类型。
Realm 特定类型 | Realm 对象 | 应用程序服务模型 | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
| ||||||||||||
|
| ||||||||||||
|
| ||||||||||||
|
| ||||||||||||
|
| ||||||||||||
|
| ||||||||||||
|
| ||||||||||||
|
| ||||||||||||
|
|