Definir un tipo de objeto de reino
Para definir un tipo de objeto Realm, cree un objeto de esquema que especifique el tipo
name y properties. El nombre del tipo debe ser único entre los tipos de objeto de un dominio. Para obtener más información sobre cómo definir propiedades específicas, consulte Definir propiedades de objeto.
Puede definir sus esquemas con clases JavaScript (como la mayoría de los ejemplos en esta página), pero también puede definirlos como objetos JavaScript.
const Car = { name: "Car", properties: { _id: "objectId", make: "string", model: "string", miles: "int?", }, };
Definir tipos de objetos de Realm con clases de JavaScript
Puedes definir tipos de objetos Realm con clases de JavaScript. Para utilizar una clase como un tipo de objeto Realm, definir el esquema de objeto en la propiedad estática 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", }; }
Nota
Los nombres de clase están limitados a un máximo de 57 caracteres UTF-8.
Pase la clase a la propiedad de esquema del objeto Realm.Configuration al abrir un dominio. De esta forma, podrá leer y escribir datos con normalidad.
const realm = await Realm.open({ path: "myrealm", schema: [Car], }); let car1; realm.write(() => { car1 = realm.create(Car, { make: "Nissan", model: "Sentra", miles: 1000, }); });
Tipos de propiedad admitidos
Cada propiedad de un objeto Realm tiene un tipo de dato claramente definido. El tipo de una propiedad puede ser un tipo de dato primitivo o un tipo de objeto definido en el mismo reino. El tipo también especifica si la propiedad contiene un único valor o una lista de valores.
Realm admite los siguientes tipos de datos primitivos:
boolpara valores booleanosintydouble, que se asignan a valoresnumberde JavaScriptDecimal128para números de alta precisiónstringdate, que corresponde a la fechadata, que se asigna a ArrayBufferobjectId, que se asigna a ObjectId
Para especificar que un campo contiene una lista de un tipo de valor primitivo, agregue [] al nombre del tipo.
Definir propiedades de objeto
Para definir una propiedad para un tipo de objeto Realm, crea un par clave-valor que represente el nombre y el tipo de dato de la propiedad en el campo properties.
El siguiente esquema define un tipo Car que tiene estas propiedades: _id make, model y 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", }; }
Especificar una propiedad opcional
Para marcar una propiedad como opcional, agregue un signo de interrogación ? a su tipo.
El siguiente esquema Car define una propiedad miles opcional de tipo int.
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", }; }
Especificar una clave principal
Para especificar una propiedad como clave principal de un tipo de objeto, establezca el campo primaryKey del esquema en el nombre de la propiedad.
Nota
Una clave principal es una propiedad que identifica de forma única a un objeto. Realm indexa automáticamente las propiedades de clave principal, lo que permite leer y modificar objetos de forma eficiente según su clave principal.
Si un tipo de objeto tiene una clave principal, todos los objetos de ese tipo deben incluir la propiedad de clave principal con un valor único entre los objetos del mismo tipo en un dominio. Un tipo de objeto puede tener como máximo una clave principal. No se puede cambiar la propiedad de clave principal de un tipo de objeto después de añadir cualquier objeto de ese tipo a un dominio, ni tampoco se puede modificar el valor de la clave principal de un objeto.
El siguiente esquema de objeto Car especifica la propiedad _id como su clave principal.
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", }; }
Indexar una propiedad
Realm admite la indexación de propiedades de cadena, entero, booleano, Date, UUID y ObjectId. Para definir un índice para una propiedad determinada, establezca indexed en true.
Nota
Un índice aumenta significativamente la velocidad de ciertas operaciones de lectura a costa de tiempos de escritura ligeramente más lentos y de un mayor uso de almacenamiento y memoria. Realm almacena índices en disco, lo que hace que sus archivos de Realm sean más grandes. Cada entrada de índice consta de un mínimo de 12 bytes. El ordenamiento de las entradas de índice admite coincidencias exactas eficientes y operaciones de query basadas en rangos.
Es mejor agregar índices solo cuando se optimiza el rendimiento de lectura para situaciones específicas.
El siguiente esquema de objeto Car define un índice en la propiedad _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", }; }
Establecer un índice de búsqueda de texto completo
Además de los índices estándar, Realm también admite índices de búsqueda de texto completo (FTS) en propiedades de cadena. Si bien se puede consultar un campo de cadena con o sin un índice estándar, un índice FTS permite buscar múltiples palabras y frases, excluyendo otras.
Para obtener más información sobre cómo consultar índices FTS, consulte Filtrar con búsqueda de texto completo.
Para crear un índice FTS, establezca el tipo de indexación 'full-text' en. Esto permite realizar consultas de texto completo en la propiedad. En el siguiente ejemplo, establecemos el tipo de indexación de la name propiedad 'full-text' en:
class Book extends Realm.Object<Book> { name!: string; price?: number; static schema: ObjectSchema = { name: "Book", properties: { name: { type: "string", indexed: "full-text" }, price: "int?", }, }; }
Definir un valor de propiedad predeterminado
Para definir un valor predeterminado, establezca el valor de la propiedad en un objeto con un campo type y un campo default.
El siguiente esquema de objeto Car especifica un valor predeterminado de 0 para la propiedad miles:
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", }; }
Asignar una propiedad o clase a un nombre diferente
De forma predeterminada, Realm usa el nombre definido en la clase del modelo para representar internamente las clases y los campos. En algunos casos, podría ser conveniente cambiar este comportamiento. Por ejemplo:
Para facilitar el trabajo en plataformas donde las convenciones de nomenclatura difieren. Por ejemplo, si los nombres de las propiedades del esquema de sincronización de dispositivos usan mayúsculas y minúsculas, mientras que el proyecto usa mayúsculas y minúsculas.
Para cambiar un nombre de clase o campo sin forzar una migración.
Para admitir múltiples clases de modelos con el mismo nombre en diferentes paquetes.
Para utilizar un nombre de clase que sea más largo que el límite de 57caracteres impuesto por Realm.
Puedes asignar el nombre de una clase o propiedad en tu código a otro nombre para almacenarlo en un dominio. Si escribes en un dominio sincronizado, el esquema de sincronización ve los valores almacenados con el nombre de la clase o propiedad persistente.
Tenga en cuenta que las migraciones deben usar el nombre de propiedad o clase persistente, y cualquier error de esquema informado también usa el nombre persistente.
Para utilizar en su código un nombre de clase diferente al que está almacenado en un reino:
Establezca la
namepropiedad del esquema de su objeto Realm con el nombre que desea utilizar para almacenar el objeto.Utilice el nombre de la clase en la
schemapropiedad de la configuración del reino cuando abra el reino.Utilice el nombre asignado para realizar operaciones CRUD o al definir suscripciones de sincronización flexible.
En el siguiente ejemplo, Realm almacena los objetos creados con la clase Task como 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`);
Para utilizar en su código un nombre de propiedad diferente al que está almacenado en un reino, configure mapTo con el nombre de la propiedad tal como aparece en su código.
En el siguiente esquema de objeto Car, Realm almacena el nombre del modelo del coche con la propiedad model_name de caso de serpiente. El esquema asigna la propiedad a modelName para los objetos utilizados en el código de cliente.
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", }; }
Definir propiedades de relación
Tip
Alternativamente, puede definir sus relaciones en su aplicación App Services.
Definir una propiedad de relación de uno a uno
Una relación de uno a uno asigna una propiedad a una sola instancia de otro tipo de objeto. Por ejemplo, se puede modelar un fabricante con un solo coche como máximo como una relación de uno a uno.
Para definir una propiedad de relación de uno a uno, especifique el nombre del tipo de objeto relacionado como el tipo de propiedad.
Importante
Las relaciones de uno a uno deben ser opcionales
Al declarar una relación "a-uno" en el modelo de objetos, esta debe ser una propiedad opcional. Si se intenta que la relación "a-uno" sea obligatoria, Realm genera una excepción en tiempo de ejecución.
El siguiente esquema de objeto Manufacturer especifica que un fabricante puede o no fabricar un solo Car. Si fabrican un Car, Realm lo vincula a través de la propiedad 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?", }, }; }
Definir una propiedad de relación de muchos
Una relación a muchos asigna una propiedad a cero o más instancias de otro tipo de objeto. Por ejemplo, se puede modelar un fabricante con cualquier número de automóviles como una relación a muchos.
Para definir una propiedad de relación de muchos, especifique el nombre del tipo de objeto relacionado como una lista.
Una aplicación podría usar los siguientes esquemas de objetos para indicar que un Manufacturer puede crear múltiples objetos Car incluyéndolos en su propiedad cars:
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?", }, }; }
Definir una propiedad de relación inversa
Una propiedad de relación inversa es una relación de retroenlace automática. Realm actualiza automáticamente las relaciones implícitas al añadir o eliminar un objeto en una lista de correspondencia múltiple. No se puede establecer manualmente el valor de una propiedad de relación inversa.
Para definir una propiedad de relación inversa, establezca el tipo de propiedad en linkingObjects y especifique el tipo de objeto y el nombre de la propiedad que definen la relación a invertir.
Una aplicación podría utilizar los siguientes esquemas de objetos para indicar que un Manufacturer puede crear muchos objetos Car y que cada Car debería realizar un seguimiento automático de cuál Manufacturer lo crea.
- La propiedad
carsdel objetoManufacturerse define como una relación de muchos - con
Carobjetos y contiene todos los automóviles de un fabricante determinado.
- La propiedad
- La propiedad
assigneedel objetoCarinvierte la relación y - se actualiza automáticamente para hacer referencia a cualquier objeto
Manufacturerque contenga el automóvil en su propiedadcars.
- La propiedad
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", }, }, }; }
Definir una propiedad de objeto incrustado
Para definir un modelo de objeto Realm con un objeto incrustado (objeto Realm anidado), establezca embedded en true.
Un objeto incrustado existe como datos anidados dentro de un único objeto principal específico. Hereda el ciclo de vida de su objeto principal y no puede existir como un objeto independiente de Realm. Realm elimina automáticamente los objetos incrustados si se elimina su objeto principal o si se sobrescriben con una nueva instancia de objeto incrustado. Los objetos incrustados no pueden tener una clave principal.
Puede hacer referencia a un tipo de objeto incrustado desde tipos de objetos principales de la misma manera que una relación.
El siguiente ejemplo requiere dos esquemas principales, Manufacturer y Car. La aplicación requiere un esquema secundario Warranty incrustado. Un objeto Manufacturer puede incrustar una lista de Warranty objetos, mientras que un objeto Car solo puede incrustar un único objeto 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", }, }; }
Definir un objeto asimétrico
Cambiado en la versión 12.2.1.
Si está utilizando Flexible Sync y necesita sincronizar una colección unidireccionalmente desde su dispositivo a su base de datos Atlas, puede configurar la propiedad asymmetric en su esquema de objeto.
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", }, }; }
En las versiones 12.2.0 y anteriores del SDK de Node.js, no se pueden vincular objetos asimétricos a tipos Realm.Object. En las versiones 12.2.1 y posteriores del SDK, los objetos asimétricos pueden vincularse a tipos Realm.Object, además de a objetos incrustados.
Nota
Intentando leer objetos asimétricos
No se pueden leer objetos asimétricos. Si intenta consultar un objeto asimétrico, obtendrá el siguiente error: "Error: No se puede consultar una clase asimétrica".
Para obtener más información sobre la ingesta de datos, lea Optimizar la sincronización con la ingesta de datos.
Definir datos no estructurados
Nuevo en la versión 12.9.0.
A partir de la versión del SDK de Node.js,12.9.0 se pueden almacenar colecciones de datos mixtos dentro de una mixed propiedad. Esta función permite modelar estructuras de datos complejas, como documentos JSON o MongoDB, sin necesidad de definir un modelo de datos estricto.
Los datos no estructurados son aquellos que no se ajustan fácilmente a un esquema esperado, lo que dificulta o hace poco práctico modelarlos para clases de datos individuales. Por ejemplo, su aplicación podría tener datos muy variables o dinámicos cuya estructura se desconoce en tiempo de ejecución.
Almacenar colecciones en una propiedad mixta ofrece flexibilidad sin sacrificar la funcionalidad, incluyendo una sincronización eficiente al usar Device Sync. Además, puede trabajar con ellas de la misma manera que con una colección no mixta:
Puedes anidar colecciones mixtas hasta 100 niveles.
Puede consultar y reaccionar ante los cambios en colecciones mixtas.
Puede buscar y actualizar elementos de colección mixtos individuales.
Sin embargo, almacenar datos en colecciones mixtas tiene menos rendimiento que usar un esquema estructurado o serializar blobs JSON en una única propiedad de cadena.
Para modelar datos no estructurados en su aplicación, defina las propiedades adecuadas en su esquema como tipos mixtos. A continuación, puede configurar estas mixed propiedades como una lista o un diccionario de elementos mixtos. Tenga en cuenta que mixed no puede representar un conjunto ni un objeto incrustado.
Tip
Utilice un mapa de tipos de datos mixtos cuando el tipo sea desconocido pero cada valor tendrá un identificador único.
Utilice una lista de tipos de datos mixtos cuando el tipo sea desconocido, pero el orden de los objetos sea importante.