Docs Menu
Docs Home
/ /
Atlas Device SDK
/ /

Realm オブジェクトモデルの定義 - Node.js SDK

項目一覧

  • Realm オブジェクトタイプの定義
  • JavaScript クラスを使用した Realm オブジェクト型の定義
  • サポートされているプロパティの型
  • オブジェクト プロパティを定義する
  • 任意プロパティを指定する
  • プライマリキーの指定
  • プロパティのインデックス作成
  • 全文検索インデックスの設定
  • デフォルトのプロパティ値を定義する
  • プロパティまたはクラスを別の名前にマッピング
  • 関係プロパティを定義する
  • To-1 の関係プロパティの定義
  • ToMany 関係プロパティの定義
  • 逆の関係プロパティを定義する
  • 埋め込みオブジェクト プロパティの定義
  • 非対称オブジェクトの定義
  • 非構造化データの定義

Realm オブジェクトタイプを定義するには、タイプの namepropertiesを指定する スキーマ オブジェクト を作成します。 タイプ名は、Realm 内のオブジェクトタイプ間で一意である必要があります。 特定のプロパティを定義する方法の詳細については、「 オブジェクト プロパティの定義 」を参照してください。

JavaScript クラスを使用してスキーマを定義できます(このページのほとんどの例と同様)が、JavaScript オブジェクトとして定義することもできます。

const Car = {
name: "Car",
properties: {
_id: "objectId",
make: "string",
model: "string",
miles: "int?",
},
};

JavaScript クラスを使用して Realm オブジェクトタイプを定義できます。 クラスをオブジェクトタイプとして使用するには、静的プロパティschemaでオブジェクト スキーマを定義します。

class Car extends Realm.Object {
static schema = {
name: "Car",
properties: {
_id: { type: "objectId", default: () => new Realm.BSON.ObjectId() },
make: "string",
model: "string",
miles: "int?",
},
primaryKey: "_id",
};
}

注意

クラス名は最大 57 文字の UTF-8 文字に制限されています。

Realm を開くときに、クラス自体をRealm.Configurationオブジェクトのスキーマ プロパティに渡します。 その後は通常通りデータの読み取りと書込みができるようになります。

const realm = await Realm.open({
path: "myrealm",
schema: [Car],
});
let car1;
realm.write(() => {
car1 = realm.create(Car, {
make: "Nissan",
model: "Sentra",
miles: 1000,
});
});

Realm オブジェクト内のすべてのプロパティには、厳密に定義されたデータ型があります。 プロパティの型は、プリミティブ データ型または同じ Realm で定義されたオブジェクト型にすることができます。 また、 型は、プロパティに単一の値が含まれているか、値のリストが含まれているかを指定します。

Realm は次のプリミティブ データ型をサポートしています。

プリミティブ値型のリストがフィールドに含まれていることを指定するには、型名に[]を追加します。

オブジェクトタイプのプロパティを定義するには、 propertiesフィールドの下にプロパティの名前とデータ型を表すキーと値のペアを作成します。

次のスキーマでは、 _id makemodelmilesのこれらのプロパティを持つCar型を定義します。

class Car extends Realm.Object {
static schema = {
name: "Car",
properties: {
_id: { type: "objectId", default: () => new Realm.BSON.ObjectId() },
make: "string",
model: "string",
miles: "int?",
},
primaryKey: "_id",
};
}

プロパティを任意としてマークするには、そのタイプに疑問符?を追加します。

次のCarスキーマでは、 intタイプの任意のmilesプロパティを定義しています。

class Car extends Realm.Object {
static schema = {
name: "Car",
properties: {
_id: { type: "objectId", default: () => new Realm.BSON.ObjectId() },
make: "string",
model: "string",
miles: "int?",
},
primaryKey: "_id",
};
}

オブジェクトタイプのプライマリキーとしてプロパティを指定するには、スキーマのprimaryKeyフィールドをプロパティ名に設定します。

注意

プライマリキーは、オブジェクトを一意に識別するプロパティです。 Realm はプライマリキー プロパティを自動的にインデックス化します。これにより、プライマリキーに基づいてオブジェクトを効率的に読み取り、変更できます。

オブジェクトタイプにプライマリキーがある場合、そのタイプのすべてのオブジェクトには、Realm 内の同じタイプのオブジェクト間で一意の値を持つプライマリキー プロパティが含まれている必要があります。 オブジェクトタイプには、最大 1 つのプライマリキーを含めることができます。 オブジェクトタイプのプライマリキー プロパティは、そのタイプのオブジェクトが Realm に追加された後は変更できず、オブジェクトのプライマリキー値を変更することはできません。

次のCarオブジェクト スキーマでは、 _idプロパティをプライマリキーとして指定します。

class Car extends Realm.Object {
static schema = {
name: "Car",
properties: {
_id: { type: "objectId", default: () => new Realm.BSON.ObjectId() },
make: "string",
model: "string",
miles: "int?",
},
primaryKey: "_id",
};
}

Realmは、 string 、整数、ブール値、DateUUIDObjectId プロパティのインデックス作成をサポートしています。 特定のプロパティのインデックスを定義するには、 indexedtrueに設定します。

注意

インデックスにより、特定の読み取り操作の速度が大幅に向上しますが、書込み時間が若干遅くなり、ストレージとメモリのオーバーヘッドが増加します。 Realm はインデックスをディスクに保存するため、Realm ファイルが大きくなります。 各インデックスエントリは 12 バイト以上です。 インデックス エントリの順序付けは、効率的な等価一致と範囲ベースのクエリ操作をサポートします。

特定の状況に合わせて読み取りパフォーマンスを最適化する場合にのみインデックスを追加することをお勧めします。

次のCarオブジェクト スキーマは、 _idプロパティのインデックスを定義します。

class Car extends Realm.Object {
static schema = {
name: "Car",
properties: {
_id: { type: "objectId", indexed: true },
make: "string",
model_name: { type: "string", mapTo: "modelName" },
miles: { type: "int", default: 0 },
},
primaryKey: "_id",
};
}

標準インデックスに加えて、Realm は string プロパティの全文検索(FTS)インデックスもサポートしています。 標準インデックスの有無にかかわらず string フィールドをクエリできますが、FTS インデックスを使用すると複数の単語とフレーズを検索し、その他を除外できます。

FTS インデックスのクエリの詳細については、「全文検索でのフィルタリング 」を参照してください。

FTS インデックスを作成するには、インデックス付きタイプを'full-text'に設定します。 これにより、プロパティに対する全文クエリが可能になります。 次の例では、 nameプロパティのインデックス付きタイプを'full-text'に設定します。

class Book extends Realm.Object<Book> {
name!: string;
price?: number;
static schema: ObjectSchema = {
name: "Book",
properties: {
name: { type: "string", indexed: "full-text" },
price: "int?",
},
};
}

デフォルト値を定義するには、プロパティの値をtypeフィールドとdefaultフィールドを持つオブジェクトに設定します。

次のCarオブジェクト スキーマでは、 milesプロパティにデフォルト値0を指定しています。

class Car extends Realm.Object {
static schema = {
name: "Car",
properties: {
_id: { type: "objectId", indexed: true },
make: "string",
model_name: { type: "string", mapTo: "modelName" },
miles: { type: "int", default: 0 },
},
primaryKey: "_id",
};
}

デフォルトでは、Realm はモデル クラスで定義された名前を使用して、クラスとフィールドを内部的に表します。 場合によっては、この動作を変更することをお勧めします。 例:

  • 命名規則が異なるプラットフォーム間での操作を容易にします。 たとえば、Device Sync スキーマのプロパティ名がスニペットのケースを使用する場合、プロジェクトはキャメルケースを使用します。

  • 移行を強制せずにクラスまたはフィールド名を変更します。

  • 異なるパッケージで同じ名前の複数のモデル クラスをサポートします。

  • Realm によって強制される 57 文字の制限よりも長いクラス名を使用します。

コード内のクラス名またはプロパティ名を別の名前にマッピングして、Realm に保存できます。 同期された Realm に書き込むと、Sync スキーマは永続化されたクラスまたはプロパティ名を使用して保存された値を確認します。

移行では永続化されたクラスまたはプロパティ名を使用する必要があり、報告されたスキーマ エラーも永続化された名前を使用することに注意してください。

Realm に保存されているものとは異なるクラス名をコード内で使用するには、次の手順に従います。

  1. Realm オブジェクトのスキーマnameプロパティを、オブジェクトの保存に使用する名前に設定します。

  2. Realm を 開く ときに、Realm 構成の プロパティで クラス 名を使用します。schema

  3. CRUD 操作を実行するため、または Flexible Sync サブスクリプションを定義する場合は、マップされた名前を使用します。

次の例では、Realm はTaskクラスで作成されたオブジェクトをTodo_Itemとして保存します。

class Task extends Realm.Object {
static schema = {
// Set the schema's `name` property to the name you want to store.
// Here, we store items as `Todo_Item` instead of the class's `Task` name.
name: "Todo_Item",
properties: {
_id: "int",
name: "string",
owner_id: "string?",
},
primaryKey: "_id",
};
}
const config = {
// Use the class name in the Configuration's `schema` property when
// opening the realm.
schema: [Task],
sync: {
user: anonymousUser,
flexible: true,
initialSubscriptions: {
update: (subs, realm) => {
subs.add(
realm
// Use the mapped name in Flexible Sync subscriptions.
.objects(`Todo_Item`)
.filtered(`owner_id == "${anonymousUser.id}"`)
);
},
},
},
};
const realm = await Realm.open(config);
realm.write(() => {
// Use the mapped name when performing CRUD operations.
realm.create(`Todo_Item`, {
_id: 12342245,
owner_id: anonymousUser.id,
name: "Test the Todo_Item object name",
});
});
// Use the mapped name when performing CRUD operations.
const assignedTasks = realm.objects(`Todo_Item`);
class Task extends Realm.Object<Task> {
_id!: number;
name!: string;
owner_id?: string;
static schema: ObjectSchema = {
// Set the schema's `name` property to the name you want to store.
// Here, we store items as `Todo_Item` instead of the class's `Task` name.
name: "Todo_Item",
properties: {
_id: "int",
name: "string",
owner_id: "string?",
},
primaryKey: "_id",
};
}
const config: Realm.Configuration = {
// Use the class name in the Configuration's `schema` property when
// opening the realm.
schema: [Task],
sync: {
user: anonymousUser,
flexible: true,
initialSubscriptions: {
update: (subs, realm) => {
subs.add(
realm
// Use the mapped name in Flexible Sync subscriptions.
.objects(`Todo_Item`)
.filtered(`owner_id == "${anonymousUser.id}"`)
);
},
},
},
};
const realm = await Realm.open(config);
realm.write(() => {
// Use the mapped name when performing CRUD operations.
realm.create(`Todo_Item`, {
_id: 12342245,
owner_id: anonymousUser.id,
name: "Test the Todo_Item object name",
});
});
// Use the mapped name when performing CRUD operations.
const assignedTasks = realm.objects(`Todo_Item`);

Realm に保存されているものとは異なるプロパティ名をコード内で使用するには、コードに表示されるプロパティ名にmapToを設定します。

次のCarオブジェクト スキーマでは、Realm はスニペットケースmodel_nameプロパティとともに自動車のモデル名を保存します。 スキーマは、クライアント コードで使用されるオブジェクトのmodelNameに プロパティをマッピングします。

class Car extends Realm.Object {
static schema = {
name: "Car",
properties: {
_id: { type: "objectId", indexed: true },
make: "string",
model_name: { type: "string", mapTo: "modelName" },
miles: { type: "int", default: 0 },
},
primaryKey: "_id",
};
}

Tip

以下も参照してください。

あるいは、 で 関係を定義するApp Services App こともできます。

対 1 の関係は、1 つのプロパティを別のオブジェクトタイプの 1 つのインスタンスにマッピングします。 たとえば、最大 1 台の自動車を所有するメーカーを 1 対 1 の関係としてモデル化できます。

対 1 の関係プロパティを定義するには、関連するオブジェクトタイプ名をプロパティタイプとして指定します。

重要

対 1 の関係は任意である必要があります

オブジェクトモデルで 1 の関係を宣言する場合、それは任意の プロパティである必要があります。 対 1 の関係を必要にしようとすると、Realm は実行時に例外をスローします。

次のManufacturerオブジェクト スキーマは、メーカーが単一のCarを作成するかどうかを指定します。 ドキュメントがCarを作成する場合、Realm はcarプロパティを介してそのドキュメントにリンクします。

class Manufacturer extends Realm.Object {
static schema = {
name: "Manufacturer",
properties: {
_id: "objectId",
// A manufacturer that may have one car
car: "Car?",
},
};
}
class Car extends Realm.Object {
static schema = {
name: "Car",
properties: {
_id: "objectId",
make: "string",
model: "string",
miles: "int?",
},
};
}

対多の関係は、1 つのプロパティを別のオブジェクトタイプの 0 件以上のインスタンスにマッピングします。 たとえば、任意の数の自動車を所有するメーカーを対多の関係としてモデル化できます。

対多の関係プロパティを定義するには、関連するオブジェクトタイプ名をリストとして指定します。

アプリケーションは次のオブジェクト スキーマを使用して、 carsプロパティに含めることで、 Manufacturerが複数のCarオブジェクトを作成できることを示すことができます。

class Manufacturer extends Realm.Object {
static schema = {
name: "Manufacturer",
properties: {
_id: "objectId",
// A manufacturer that may have many cars
cars: "Car[]",
},
};
}
class Car extends Realm.Object {
static schema = {
name: "Car",
properties: {
_id: "objectId",
make: "string",
model: "string",
miles: "int?",
},
};
}

逆関係プロパティは、自動バックリンク関係です。 Realm は、対応する リストでオブジェクトが追加または削除されるたびに、暗黙的な関係を自動的に更新します。 逆関係プロパティの値を手動で設定することはできません。

逆関係プロパティを定義するには、プロパティタイプをlinkingObjectsに設定し、反転する関係を定義するオブジェクトタイプとプロパティ名を指定します。

アプリケーションは次のオブジェクト スキーマを使用して、 Manufacturerが多数のCarオブジェクトを作成する可能性があり、各CarがどのManufacturerがそれを作成するかを自動的に追跡する必要があることを示します。

  • Manufacturerオブジェクトのcarsプロパティは対多の関係として定義されています
    は、 Carオブジェクトと接続し、特定のメーカーの自動車すべてを含みます。
  • Carオブジェクトのassigneeプロパティは関係を反転させ、
    は、 carsプロパティに含むすべてのManufacturerオブジェクトを参照するように自動的に更新されます。
class Manufacturer extends Realm.Object {
static schema = {
name: "Manufacturer",
properties: {
_id: "objectId",
// A manufacturer that may have many cars
cars: "Car[]",
},
};
}
class Car extends Realm.Object {
static schema = {
name: "Car",
properties: {
_id: "objectId",
make: "string",
model: "string",
miles: "int?",
// Backlink to the manufacturer. This is automatically updated whenever
// this car is added to or removed from a manufacturer's cars list.
assignee: {
type: "linkingObjects",
objectType: "Manufacturer",
property: "cars",
},
},
};
}

埋め込みオブジェクト(ネストされた Realm オブジェクト)を含む Realm オブジェクトモデルを定義するには、 embeddedtrueに設定します。

埋め込みオブジェクトは、単一の特定の親オブジェクト内にネストされたデータとして存在します。 親オブジェクトのライフサイクルを継承し、独立した Realm オブジェクトとして存在することはできません。 Realm は、親オブジェクトが削除された場合、または新しい埋め込みオブジェクト インスタンスによって上書きされた場合に、埋め込みオブジェクトを自動的に削除します。 埋め込みオブジェクトにはプライマリキーを設定できません。

埋め込みオブジェクトタイプは、関係と同じ方法で親オブジェクトタイプから参照できます。

次の例には、2 つの親スキーマ、 ManufacturerCarが必要です。 アプリケーションには埋め込み子スキーマWarrantyが必要です。 ManufacturerオブジェクトはWarrantyオブジェクトのリストを埋め込むことができますが、 Carオブジェクトには単一のWarrantyオブジェクトのみを埋め込むことができます。

class Manufacturer extends Realm.Object {
static schema = {
name: "Manufacturer",
properties: {
_id: "objectId",
name: "string",
// Embed an array of objects
warranties: { type: "list", objectType: "Warranty" },
},
};
}
class Car extends Realm.Object {
static schema = {
name: "Car",
properties: {
_id: "objectId",
make: "string",
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",
},
};
}

バージョン 12.2.1 で変更

Flexible Sync を使用していて、デバイスから Atlas データベースにコレクションを一方向に同期する必要がある場合は、オブジェクト スキーマにasymmetricプロパティを設定できます。

class WeatherSensor extends Realm.Object {
static schema = {
name: "WeatherSensor",
// Sync WeatherSensor objects one way from your device
// to your Atlas database.
asymmetric: true,
primaryKey: "_id",
properties: {
_id: "objectId",
deviceId: "string",
temperatureInFahrenheit: "int",
barometricPressureInHg: "float",
windSpeedInMph: "float",
},
};
}
class WeatherSensor extends Realm.Object<WeatherSensor> {
_id!: Realm.BSON.ObjectId;
deviceId!: string;
temperatureInFahrenheit!: number;
barometricPressureInHg!: number;
windSpeedInMph!: number;
static schema: ObjectSchema = {
name: "WeatherSensor",
// sync WeatherSensor objects one way from your device
// to your Atlas database.
asymmetric: true,
primaryKey: "_id",
properties: {
_id: "objectId",
deviceId: "string",
temperatureInFahrenheit: "int",
barometricPressureInHg: "float",
windSpeedInMph: "float",
},
};
}

Node.js SDK バージョン 12.2.0 以前では、非対称オブジェクトからRealm.Object型へのリンクはできません。 SDK バージョン 12.2.1 以降では、非対称オブジェクトは埋め込みオブジェクトに加えてRealm.Objectタイプにリンクできます。

注意

非対称オブジェクトの読み取り試行

非対称オブジェクトは読み取れません。 非対称オブジェクトをクエリしようとすると、「エラー: 非対称クラスをクエリできません。」というエラーが表示されます。

Data Ingest の詳細については、「 Data Ingestによる同期の最適化 」を参照してください。

バージョン12.9.0の新機能

Node.js SDK バージョン12.9.0以降、 mixedプロパティ内に混合データのコレクションを保存できます。 この機能を使用すると、厳密なデータモデルを定義することなく、JSON や MongoDB ドキュメントなどの複雑なデータ構造をモデル化できます。

非構造化データとは、期待されるスキーマに簡単に準拠していないデータであるため、個々のデータ クラスにモデル化するのが困難または非効率的です。 たとえば、アプリには、実行時に構造が不明な高度に変数データや動的データがある場合があります。

コレクションを混合プロパティに保存すると、Device Sync を使用する際のパフォーマンス的な同期など、機能を犠牲にすることなく柔軟性が高まります。 そして、混合されていないコレクションと同じ方法でそれらを操作できます。

  • 混合コレクションは最大100レベルまでネストできます。

  • 混合コレクションのReactに対応する と をクエリできます。

  • 個々の混合コレクション要素を検索して更新できます。

ただし、混合コレクションにデータを保存する場合、構造化スキーマを使用したり、JSON string を単一の string プロパティに直列化したりする場合よりパフォーマンスが低くなります。

アプリで非構造化データをモデル化するには、スキーマ内の適切なプロパティを混合型 として定義します。 次に、これらのmixedプロパティを混合要素のリストまたは辞書コレクションとして設定できます。 mixedはセットまたは埋め込みオブジェクトを表すことができないことに注意してください。

Tip

  • 型が不明であるが、各値には一意の識別子が付けられる場合は、混合データ型のマップを使用します。

  • 型が不明であるが、オブジェクトの順序に意味がある場合は、混合データ型のリストを使用します。

戻る

モデルデータ