Docs Menu
Docs Home
/ /
Atlas Device SDK
/ / /

Device Sync によるモデルデータ - Kotlin SDK

項目一覧

  • Device Sync データモデルの定義
  • クライアント アプリからのスキーマの生成
  • 既存の Atlas データを使用したスキーマの生成
  • Device Sync の要件
  • Realm オブジェクトマッピング
  • Realm 関係マッピング
  • 1 つの関係をマッピング
  • 対多の関係
  • 逆の関係
  • 埋め込みオブジェクト
  • スキーマ タイプ マッピング リスト
  • Kotlin 型
  • BSON types
  • Realm のタイプ

このページでは、Device Sync データモデルと、Device Sync で使用される App Services スキーマのデータをクライアント内の Kotlin SDK で使用される Realm スキーマにマッピングするために使用される方法について説明します。

このページでは、 ではありません

Device Sync の詳細については、Atlas App Services ドキュメントの「 Atlas Device Sync を使い始める 」を参照してください。

Tip

このページの「スキーマ タイプ マッピング リスト」セクションの表は、サポートされているデータ型と、Realm と App Services 間でマップされる方法のクイック リファレンスを提供します。 より包括的なリソースについては、App Services ドキュメントの「データモデル マッピング 」を参照してください。

Atlas Device Sync データモデルは次のスキーマによって定義され、Device Sync がクライアントと Atlas 間でデータをマッピングできるようにします。

  • Realm スキーマ: Kotlin SDK を使用して Kotlin クラスとしてデータを定義するアプリ内のクライアント側オブジェクトモデル。

  • App Services schema : BSON でデータを定義する Atlas App Services のサーバーサイド スキーマ。 詳細については、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 にすでに存在するデータを操作するクライアント アプリケーションを開発する場合は、そのデータからスキーマを生成し、 Kotlin クライアント アプリで使用する SDK オブジェクトモデルを生成できます。 詳しくは、Atlas App Services ドキュメントの「クライアント アプリケーションを使用して Atlas のデータを同期する 」を参照してください。

オブジェクトを正常に同期するには、いくつかの要件があります。 前述のように、同期するオブジェクトを含む Realm と App Services の一致するスキーマが必要です。

さらに、Device Sync には次のものが必要です。

  • オブジェクトモデルには、 という プライマリキー フィールドが 必要_id です。タイプはStringInt 、またはObjectIdです。 Device Sync はこれを使用して、Atlas コレクション内のオブジェクトを識別します。

    オブジェクトに_idフィールドが定義されていない場合、Realm は次のスキーマ検証エラーをスローします: There must be a primary key property named '_id' on a synchronized Realm

  • 各クラスには、少なくとも 1 つのクエリ可能なフィールドが必要です。

    開発モードを有効にすると、クライアント サブスクリプション クエリに含めたフィールドは、Atlas のクエリ可能なフィールドとして自動的に追加されます。 Kotlin SDK を使用したサブスクリプションの構成の詳細については、「サブスクリプションの概要 」を参照してください。

Realm オブジェクトは、そのタイプのオブジェクトのプロパティと関係を決定する、Realm スキーマで定義される Kotlin クラスの一意の名前付きインスタンスです。

App Services は、Realm オブジェクトを次の方法で Atlas にマッピングします。

  • Realm オブジェクト名は、リンクされた Device Sync データソース内の Atlas コレクションにマップされます。 次の点に注意してください。

    • 開発モードが有効になっている場合、App Services は、同期する新しい Realm オブジェクト型ごとにコレクションとスキーマを自動的に作成します。

    • 埋め込みオブジェクトは、Atlas 内の独自のコレクションに保存されません。 これは、親オブジェクトタイプの外部で存在できないためです。 詳細については、このページの「埋め込みオブジェクト」セクションを参照してください。

  • Realm オブジェクト スキーマは、適切なコレクション内の App Services スキーマにマップされます。

FrogPond次の例では、Realm スキーマに基本プロパティが定義されている オブジェクトと オブジェクトがあります。

Flow および Pond Realm オブジェクト
// Maps to `Frog` collection
class Frog : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var age: Int? = null
}
// Maps to `Pond` collection
class Pond : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
}

Atlas では、これらのオブジェクト型が対応する App Services スキーマにどのようにマップされるかを確認できます。各オブジェクトはそれぞれのコレクションにマップされます。 このデータモデルに準拠するログ オブジェクトとプール オブジェクトの例も示します。

App Services の Flow コレクション
{
"title": "Frog",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"age": {
"bsonType": "long"
},
"name": {
"bsonType": "string"
}
}
}
App Services のプール コレクション
{
"title": "Pond",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"name": {
"bsonType": "string"
}
}
}
Atlas の F log オブジェクトの例
{
"_id": ObjectId("5af712eff26b29dc5c51c60f"),
"name": "Kermit",
"age": 42
}
Atlas の MongoDB オブジェクトの例
{
"_id": ObjectId("5af714eff24b294c5251cf04"),
"name": "Kermit's Pond"
}

Realm オブジェクトモデルには、オブジェクト間の関係が含まれる場合があります。 関係にはプライマリタイプの 2 つがあります。

  • 対 1 の関係: オブジェクトは、1 つの他の Realm オブジェクトのみに特定の方法で関連付けられています。

  • 対多の関係: オブジェクトが複数の Realm オブジェクトに特定の方法で関連付けられています。

関係は、他の Realm オブジェクトのプライマリキーを参照するプロパティによってマップされます。

App Services スキーマでの関係のモデル化の詳細については、App Services ドキュメントの「関係」を参照してください。

対 1 の関係は、1 つのプロパティを別の Realm オブジェクトの 1 つのインスタンスにマッピングします。 対 1 の関係は任意である必要があります。 Kotlin SDK で 1 対 1 の関係が定義されている方法の詳細については、「 対 1 の関係プロパティの定義 」を参照してください。

上記の例の オブジェクトを使用して、 Frogがお気に入りのプールを 1 つ持つことができる場合を考えてみましょう。 Pondオブジェクトへの任意リンクであるfavoritePondプロパティをFrogモデルに追加できます。

POD と 1 の関係を持つフロー型
class Frog : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var age: Int? = null
// To-one relationship (MUST be optional)
var favoritePond: Pond? = null
}

Atlas App Services スキーマでは、新しい プロパティがフィールドfavoritePondに変換されることがわかります。

  • フィールドは任意プロパティであるため、 required配列にありません。

  • そのタイプは、別のPondコレクション内の特定のPondオブジェクトにリンクするobjectIdです。 これは、 PondモデルのプライマリキーをobjectIdとして定義したためです。

Pondスキーマは変更されません。 これは 1 対 1 の関係であるため、一方向の関係になります。 PondFrogとの関係がありません。

App Services スキーマ
{
"title": "Frog",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"age": {
"bsonType": "long"
},
"favoritePond": {
"bsonType": "objectId"
},
"name": {
"bsonType": "string"
}
}
}

対多の関係関係は、1 つのプロパティを別の Realm オブジェクトの 0 個以上のインスタンスにマッピングします。 Kotlin SDK で対多の関係が定義されている方法の詳細については、「 対多の関係プロパティの定義 」を参照してください。

別のケースとして、 Frogがお気に入りのプールが 1 つではなく多数ある場合を考えてみましょう。 PondオブジェクトのリストであるfavoritePondsプロパティをFrogモデルに追加します。 コレクションにお気に入りのプールがない場合、これは空のリストになります。 依存関係がお気に入りのプールを取得したら、新しいPondオブジェクトを作成し、依存関係のfavoritePondsリストに追加できます。

Pool への To-Many 関係を持つノード
class Frog : RealmObject {
@PrimaryKey
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 スキーマでは、新しい プロパティが、 Frogオブジェクトに関連するすべてのPondオブジェクトを含むfavoritePondsフィールドに変換されていることがわかります。

  • フィールドは任意プロパティであるため、 required配列にありません。

  • このフィールドの型はobjectId型の配列です。 これは、 PondモデルのプライマリキーをobjectIdとして定義したためです。

繰り返しになりますが、 PondFrogとの関係がないため、 Pondスキーマは変更されません。

App Services スキーマ
{
"title": "Frog",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"age": {
"bsonType": "long"
},
"favoritePonds": {
"bsonType": "array",
"items": {
"bsonType": "objectId"
}
},
"name": {
"bsonType": "string"
}
}
}

逆の関係は、バックリンクと呼ばれる定義済みの 1 または多対多の関係で、そのオブジェクトを参照する他のオブジェクトにオブジェクトをリンクします。 For more information on how inverse relationships are defined in Kotlin SDK, refer to Define an Inverse Relationship.

App Services スキーマは逆の関係をサポートしていません。 これは、逆関係がバックリンクが変更されると自動的に更新される Realm の暗黙的な関係を表すためです。 つまり、逆関係の値を直接設定することはできず、その関係は Atlas に存在しません。 代わりに、 Realmオブジェクトモデルに基づいて、クライアントアプリケーション内でそれらの関係をRealmし、更新します。

PondオブジェクトがFrogオブジェクトと逆の関係にある場合を考えてみましょう。

フロートとの逆関係を持つノード
class Pond : RealmObject {
@PrimaryKey
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 {
@PrimaryKey
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 スキーマでは、 FrogfavoritePondsプロパティを通じてPondと 1 対多の関係にあることがわかります。 ただし、 PondモデルのFrogへの逆の関係を表すfrogプロパティは存在しません。 これは、Atlas では逆の関係を明示的に定義できないためです。 ただし、 の関係からオブジェクトを追加または削除するたびに、Realm はそれを自動的に更新します。

App Services スキーマ
// `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"
}
}
}

埋め込みオブジェクトは、1 つの特定の親オブジェクト内にネストされたデータを表します。 関係を定義するのと同じ方法で、親オブジェクトタイプから埋め込みオブジェクトタイプを参照できます。 Kotlin SDK で埋め込みオブジェクトがどのように定義されているかの詳細については、「 埋め込みオブジェクトの定義 」を参照してください。

ただし、通常の Realm オブジェクトとは異なり、埋め込みオブジェクトは Atlas の独自のコレクションに保存されません。 代わりに、親オブジェクトのドキュメントの一部として保存され、親オブジェクト以外ではアクセスできません。

次の例では、単一の埋め込みFrog favoritePondPondオブジェクトと、多数の埋め込みForest forestPondsPondオブジェクトのリストを参照する 関係プロパティを持つ オブジェクトを参照する オブジェクトを持つ オブジェクトがあります。 :

埋め込み POD 関係を持つ Flow と Tools
class Frog : RealmObject {
@PrimaryKey
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 {
@PrimaryKey
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 スキーマでは、埋め込みオブジェクトが各親型のドキュメントにマップされていることがわかります。

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 オブジェクト型が対応する App Services スキーマ BSON タイプにどのようにマップされるかを示しています。 サポートされている App Services スキーマ タイプとそのマッピング、使用可能なプロパティの完全なリストについては、App Services ドキュメントの「データモデル マッピング 」を参照してください。

次の表は、サポートされている Kotlin データ型と、宣言されたプロパティが Realm スキーマと App Services スキーマ間でマップされる方法の例を示しています。

Kotlin SDKでサポートされている Kotlin データ型とデータモデルでそれらを定義する方法について詳しくは、「 Kotlin データ型 」を参照してください

Kotlin データ型
Realm オブジェクト
App Services スキーマ
String
var stringReq: String = ""
"stringReq": {
"bsonType": "string"
}
Byte
var byteReq: Byte = 0
"byteReq": {
"bsonType": "long"
}
Short
var shortReq: Short = 0
"shortReq": {
"bsonType": "long"
}
Int
var intReq: Int = 0
"intReq": {
"bsonType": "long"
}
Long
var longReq: Long = 0L
"longReq": {
"bsonType": "long"
}
Float
var floatReq: Float = 0.0f
"floatReq": {
"bsonType": "float"
}
Double
var doubleReq: Double = 0.0
"doubleReq": {
"bsonType": "double"
}
Boolean
var boolReq: Boolean = false
"boolReq": {
"bsonType": "bool"
}
Char
var charReq: Char = 'a'
"charReq": {
"bsonType": "long"
}

次の表は、サポートされている MongoDB BSON データ型と、宣言されたプロパティが Realm スキーマと App Services スキーマ間でマップされる方法の例を示しています。

Kotlin SDKでサポートされている MongoDB BSON データ型とデータモデルでそれらを定義する方法について詳しくは、「 Kotlin データ型 」を参照してください。

MongoDB BSON Type
Realm オブジェクト
App Services スキーマ
var objectIdReq: ObjectId = ObjectId()
"objectIdReq": {
"bsonType": "objectId"
}
Decimal128
var decimal128Req: Decimal128 = Decimal128("123.456")
"decimal128Req": {
"bsonType": "decimal"
}

次の表は、サポートされている Realm 固有のデータ型と、宣言されたプロパティが Realm スキーマと App Services スキーマ間でマップされる方法の例を示しています。

Kotlin SDKでサポートされている Realm 固有のデータ型とデータモデルでそれらを定義する方法の詳細については、「 Kotlin データ型 」を参照してください。

Realm 固有のタイプ
Realm オブジェクト
App Services スキーマ
var uuidReq: RealmUUID = RealmUUID.random()
"uuidReq": {
"bsonType": "uuid"
}
var realmInstantReq: RealmInstant = RealmInstant.now()
"realmInstantReq": {
"bsonType": "date"
}
var realmAnyOpt: RealmAny? = RealmAny.create("foo")
"realmAnyOpt": {
"bsonType": "mixed"
}
var mutableRealmIntReq: MutableRealmInt = MutableRealmInt.create(0)
"mutableRealmIntReq": {
"bsonType": "long"
}
var listReq: RealmList<CustomObjectType> = realmListOf()
"listReq": {
"bsonType": "array",
"items": {
"bsonType": "uuid"
}
}
var setReq: RealmSet<String> = realmSetOf()
"setReq": {
"bsonType": "array",
"uniqueItems": true,
"items": {
"bsonType": "string"
}
}
var dictionaryReq: RealmDictionary<String> = realmDictionaryOf()
"dictionaryReq": {
"bsonType": "object",
"additionalProperties": {
"bsonType": "string"
}
}
var realmObjectPropertyOpt: CustomObjectType? = null
"realmObjectPropertyOpt": {
"bsonType": "<PRIMARY_KEY_TYPE>"
}
var embeddedProperty: EmbeddedObjectType? = null
"embeddedProperty": {
"title": "EmbeddedObjectType",
"type": "object",
"required": [],
"properties": {
"name": {
"bsonType": "string"
}
}
}

戻る

オブジェクトモデルの変更