Docs 主页 → 开发应用程序 → Atlas Device SDKs
定义 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.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
,它们映射到 JavaScript 的number
值Decimal128
对于高精度数字string
date
,映射到日期data
,它映射到 ArrayBufferobjectId
,映射到ObjectId
要指定字段包含原始值类型的列表,请在类型名称后面添加 []
。
定义对象属性
要定义对象类型的属性,请在properties
字段下创建表示属性名称和数据类型的键值对。
以下模式定义了具有以下属性的 Car
类型:_id
make
、model
和 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", }; }
指定可选属性
若要将属性标记为可选属性,请在属性类型后附加一个问号 ?
。
以下 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 中相同类型的对象中,该主键属性具有唯一值。一个对象类型只能有一个主键。将某个对象类型的任何对象添加到 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 支持为字符串、整数、布尔值、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 还支持对字符串属性创建 Atlas 全文搜索索引。虽然无论是否使用标准索引都可以查询字符串字段,但 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,则同步模式会看到使用持久类或属性名称存储的值。
请注意,迁移必须使用持久化类或属性名称,任何模式错误报告也必须使用持久化名称。
定义关系属性
提示
另请参阅:
或者,您可以在 App Services 应用程序中定义关系。
定义对一关系属性
对一关系将一个属性映射到另一种对象类型的单个实例。例如,您可以将最多拥有一款汽车的制造商建模为对一关系。
要定义一对一关系属性,请将相关对象类型名称指定为属性类型。
重要
对一关系必须是可选的
在对象模型中声明对一关系时,它必须是一个可选属性。如果您尝试建立所需的对一关系,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?", }, }; }
定义对多关系属性
对多关系将一个属性映射到另一种对象类型的零个或多个实例。例如,您可以将拥有任意款数汽车的制造商建模为对多关系。
要定义对多关系属性,请以列表形式指定相关对象类型名称。
应用程序可以使用以下对象模式来指示 Manufacturer
可以通过在其 cars
属性中包含多个 Car
对象来创建多个 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 则会自动删除该嵌入式对象。嵌入式对象无法具备主键。
可以使用与关系相同的方式从父对象类型引用嵌入式对象类型。
以下示例需要两个父模式,即 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
属性。
在 Node.js SDK 版本 12.2.0 及更早版本中,您无法从非对称对象链接到 Realm.Object
类型。在 SDK 版本 12.2.1 及更高版本中,除了嵌入式对象以外,非对称对象还可以链接到 Realm.Object
类型。
注意
尝试读取非对称对象
无法读取非对称对象。如果尝试查询非对称对象,您将收到以下错误:“错误:无法查询非对称类。”
要了解有关数据导入的更多信息,请阅读使用数据导入优化同步。