Docs 菜单
Docs 主页
/ /
Atlas Device SDKs
/ /

定义 Realm 对象模型 - React Native SDK

在此页面上

  • 定义对象类型
  • 支持的属性类型
  • 定义对象属性
  • 声明可选属性
  • 声明主键
  • 为属性创建索引
  • 设置全文搜索索引
  • 设置默认属性值
  • 重新映射属性
  • 定义非对称对象
  • 定义非结构化数据
  • TypeScript 和必需属性

要定义 Realm 对象类型,请创建一个扩展 Realm.Object 的类。在静态属性 name 中定义类型的 propertiesschema。在 Realm 中的对象类型中,该类型的名称必须是唯一的。

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

然后,您可以在打开域时将类本身传递给配置对象的模式属性。

Realm 对象中的每个属性都有一个明确定义的数据类型。属性的类型可以是原始数据类型,也可以是在同一个 Realm 中定义的对象类型。类型还指定了属性是包含单个值还是包含值的列表。

要指定字段包含原始值类型的列表,请在类型名称后面添加 []

有关支持的属性类型的列表,请参阅属性类型

要定义对象类型的属性,请在properties字段下创建表示属性名称和数据类型的键值对。

以下模式定义了具有以下属性的 Car 类型:_id makemodelmiles

要将属性标记为可选,请使用对象语法并将 optional 设置为 true。您还可以使用简化的语法:将问号 ? 附加到类型。这最适合基本类型。对于更复杂的类型,应使用更具体的对象语法。

在下面的 Person 类示例中,agebirthday 属性都是可选的。

class Person extends Realm.Object<Person> {
name!: string;
age?: number;
birthday?: Date;
static schema: ObjectSchema = {
name: 'Person',
properties: {
name: 'string',
age: {
type: 'int',
optional: true,
},
// You can use a simplified syntax instead. For
// more complicated types, use the object syntax.
birthday: 'date?',
},
};
}

要将某个属性指定为对象类型的主键,请将模式的 primaryKey 字段设置为属性名称。

注意

主键是唯一标识对象的属性。 Realm 会自动对主键属性进行索引,这允许您根据主键高效地读取和修改对象。

如果某个对象类型具有主键,则该类型的所有对象都必须包含主键属性,并且在 Realm 中相同类型的对象中,该主键属性具有唯一值。一个对象类型只能有一个主键。将某个对象类型的任何对象添加到 Realm 后,您无法更改该对象类型的主键属性,也无法修改对象的主键值。

在以下 Task 类的示例中,我们将 _id 属性指定为主键。

1class Task extends Realm.Object {
2 static schema = {
3 name: 'Task',
4 properties: {
5 _id: 'int',
6 name: 'string',
7 priority: 'int?',
8 progressMinutes: 'int?',
9 assignee: 'Person?',
10 },
11 primaryKey: '_id',
12 };
13}
1class Task extends Realm.Object<Task> {
2 _id!: number;
3 name!: string;
4 priority?: number;
5 progressMinutes?: number;
6 assignee?: Person;
7 age?: number;
8
9 static schema: ObjectSchema = {
10 name: 'Task',
11 properties: {
12 _id: 'int',
13 name: 'string',
14 priority: 'int?',
15 progressMinutes: 'int',
16 assignee: 'Person?',
17 },
18 primaryKey: '_id',
19 };
20}

如果经常根据特定属性执行读取操作,则可以为该属性建立索引以优化性能。Realm 支持为字符串、整数、布尔值、DateUUIDObjectId 属性建立索引。

注意

索引显著提高了某些读取操作的速度,但代价是写入速度略微下降,并增加了存储和内存开销。Realm 将索引存储在磁盘上,这会使您的 Realm 文件更大。每个索引条目至少有 12 个字节。索引条目的排序支持高效的相等匹配和基于范围的查询操作。

要为给定属性建立索引,请将该属性的 indexed 字段设置为 true

在以下 Book 类的示例中,我们在 name 属性上定义了一个索引。

1class Book extends Realm.Object {
2 static schema = {
3 name: 'Book',
4 properties: {
5 name: {type: 'string', indexed: true},
6 price: 'int?',
7 },
8 };
9}
1class Book extends Realm.Object<Book> {
2 name!: string;
3 price?: number;
4
5 static schema: ObjectSchema = {
6 name: 'Book',
7 properties: {
8 name: {type: 'string', indexed: true},
9 price: 'int?',
10 },
11 };
12}

除了标准索引外,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 类的示例中,我们定义了一个默认值为 0miles 属性。

11.1.0 版新增功能

在 Realm.js v11.1.0 及更高版本中,您可以使用函数来定义动态默认值,例如下例中的 timestamp 属性。

1class Car extends Realm.Object {
2 static schema = {
3 name: 'Car',
4 properties: {
5 make: 'string',
6 model: 'string',
7 miles: {type: 'int', default: 0},
8 timestamp: {
9 type: 'int',
10 default: () => Math.round(new Date().getTime() / 1000),
11 },
12 },
13 };
14}
1class Car extends Realm.Object {
2 make!: string;
3 model!: string;
4 miles: number = 0;
5 timestamp: number = Math.round(new Date().getTime() / 1000);
6
7 static schema: ObjectSchema = {
8 name: 'Car',
9 properties: {
10 make: 'string',
11 model: 'string',
12 miles: {type: 'int', default: 0},
13 timestamp: {
14 type: 'int',
15 default: () => Math.round(new Date().getTime() / 1000),
16 },
17 },
18 };
19}

要在代码中使用与 Realm 中存储的属性名称不同的属性名称,请将 mapTo 设置为代码中显示的属性名称。

在以下 Employee 类的示例中,我们将 first_name 属性重映射到 firstName

1class Employee extends Realm.Object {
2 static schema = {
3 name: 'Employee',
4 properties: {
5 _id: 'string',
6 first_name: {type: 'string', mapTo: 'firstName'},
7 },
8 primaryKey: '_id',
9 };
10}
1class Employee extends Realm.Object {
2 _id!: string;
3 first_name!: string;
4
5 static schema: ObjectSchema = {
6 name: 'Employee',
7 properties: {
8 _id: 'string',
9 first_name: {type: 'string', mapTo: 'firstName'},
10 },
11 primaryKey: '_id',
12 };
13}

如果您使用 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',
},
};
}

在版本 realm@12.2.1 中进行了更改

在 JS SDK 版本 12.2.0 及更早版本中,您无法从非对称对象链接到 Realm.Object 类型。在 SDK 版本 12.2.1 及更高版本中,除了嵌入式对象以外,非对称对象还可以链接到 Realm.Object 类型。

注意

尝试读取非对称对象

无法读取非对称对象。如果尝试查询非对称对象,您将收到以下错误:“错误:无法查询非对称类。”

要了解有关数据导入的更多信息,请参阅将数据流式传输到 Atlas

realm@12.9.0 版本中的新增功能

从JavaScript SDK 版本 12.9.0 开始, 您可以在mixed属性中存储混合数据的集合。 您可以使用此功能对复杂的数据结构(例如JSON或MongoDB文档)进行建模,而无需定义严格的数据模型。

非结构化数据是指不容易符合预期模式的数据,因此对单个数据类进行建模很困难或不切实际。 示例,您的应用可能具有高度可变的数据或动态数据,其结构在运行时未知。

将集合存储在混合属性中可在不牺牲功能的情况下提供灵活性,包括使用Device Sync时的性能同步。 您可以像使用非混合集合一样使用它们:

  • 您最多可以嵌套100级混合集合。

  • 您可以对混合集合的React进行查询和响应。

  • 您可以查找并更新单个混合集合元素。

但是,与使用结构化模式或将JSON blob 序列化为单个string属性相比,在混合集合中存储数据的性能较低。

要对应用中的非结构化数据进行建模,请在模式中将适当的属性定义为混合类型。 然后,您可以设立这些mixed属性设置为混合元素的列表字典集合。 请注意, mixed属性不能保存设立或嵌入式对象。

提示

  • 当类型未知但每个值都有唯一标识符时,请使用混合数据类型的映射。

  • 当类型未知但对象的顺序有意义时,请使用混合数据类型的列表。

我们建议使用 Realm.create() 创建 Realm 对象 ,但您也可以对对象模型的类使用new 操作符。

如果您使用 new,则在扩展 Realm.Object 时,必须将您的类作为泛型添加,并添加任何必需的属性。这将为您的对象模型提供完整的 TypeScript 支持,包括未定义必需字段时的类型错误。

class Book extends Realm.Object<Book, 'name' | 'store'> {
name!: string;
store!: string;
price?: number;
static schema: ObjectSchema = {
name: 'Book',
properties: {
name: {type: 'string', indexed: true},
store: 'string',
price: 'int?',
},
};
}

后退

模型数据