Realm オブジェクトモデルの定義 - Node.js SDK
項目一覧
Realm オブジェクトタイプの定義
Realm オブジェクトタイプを定義するには、タイプの name
とproperties
を指定する スキーマ オブジェクト を作成します。 タイプ名は、Realm 内のオブジェクトタイプ間で一意である必要があります。 特定のプロパティを定義する方法の詳細については、「 オブジェクト プロパティの定義 」を参照してください。
JavaScript クラスを使用してスキーマを定義できます(このページのほとんどの例と同様)が、JavaScript オブジェクトとして定義することもできます。
const Car = { name: "Car", properties: { _id: "objectId", make: "string", model: "string", miles: "int?", }, };
JavaScript クラスを使用した Realm オブジェクト型の定義
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 は次のプリミティブ データ型をサポートしています。
bool
ブール値の場合int
とdouble
は JavaScriptnumber
値にマッピングしますDecimal128
高精度数値の場合string
data
は、配列バッファにマップされ ますobjectId
は、 ObjectIdにマッピングします
プリミティブ値型のリストがフィールドに含まれていることを指定するには、型名に[]
を追加します。
オブジェクト プロパティを定義する
オブジェクトタイプのプロパティを定義するには、 properties
フィールドの下にプロパティの名前とデータ型を表すキーと値のペアを作成します。
次のスキーマでは、 _id
make
、 model
、 miles
のこれらのプロパティを持つ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 、整数、ブール値、Date
、UUID
、ObjectId
プロパティのインデックス作成をサポートしています。 特定のプロパティのインデックスを定義するには、 indexed
をtrue
に設定します。
注意
インデックスにより、特定の読み取り操作の速度が大幅に向上しますが、書込み時間が若干遅くなり、ストレージとメモリのオーバーヘッドが増加します。 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 に保存されているものとは異なるクラス名をコード内で使用するには、次の手順に従います。
Realm オブジェクトのスキーマの
name
プロパティを、オブジェクトの保存に使用する名前に設定します。Realm を 開く ときに、Realm 構成の プロパティで クラス 名を使用します。
schema
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", }; }
関係プロパティを定義する
To-1 の関係プロパティの定義
対 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?", }, }; }
ToMany 関係プロパティの定義
対多の関係は、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 オブジェクトモデルを定義するには、 embedded
をtrue
に設定します。
埋め込みオブジェクトは、単一の特定の親オブジェクト内にネストされたデータとして存在します。 親オブジェクトのライフサイクルを継承し、独立した Realm オブジェクトとして存在することはできません。 Realm は、親オブジェクトが削除された場合、または新しい埋め込みオブジェクト インスタンスによって上書きされた場合に、埋め込みオブジェクトを自動的に削除します。 埋め込みオブジェクトにはプライマリキーを設定できません。
埋め込みオブジェクトタイプは、関係と同じ方法で親オブジェクトタイプから参照できます。
次の例には、2 つの親スキーマ、 Manufacturer
とCar
が必要です。 アプリケーションには埋め込み子スキーマ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
型が不明であるが、各値には一意の識別子が付けられる場合は、混合データ型のマップを使用します。
型が不明であるが、オブジェクトの順序に意味がある場合は、混合データ型のリストを使用します。