Menu Docs
Página inicial do Docs
/ /
Atlas Device SDKs
/ /

Definir um modelo de objeto de domínio - SDK do Node.js

Nesta página

  • Definir um tipo de objeto de domínio
  • Definir tipos de objetos de domínio com classes JavaScript
  • Tipos de propriedade suportados
  • Defina propriedades do objeto
  • Especificar uma propriedade opcional
  • Especificar uma chave primária
  • Indexe uma propriedade
  • Definir um índices the busca de texto completa
  • Definir um valor de propriedade padrão
  • Mapear uma propriedade ou classe para um nome diferente
  • Definir Propriedades de Relacionamento
  • Definir uma propriedade de relacionamento um-para-um
  • Definir uma propriedade de relacionamento um-para-muitos
  • Definir uma propriedade de relacionamento inversa
  • Definir uma propriedade de objeto embarcado
  • Definir um objeto assimétrico
  • Definir dados não estruturados

To define a Realm object type, create a schema object that specifies the type's name and properties. The type name must be unique among object types in a realm. For details on how to define specific properties, see Define Object Properties.

Você pode definir seus esquemas com classes JavaScript (como a maioria dos exemplos nesta página), mas você também pode defini-los como objetos JavaScript.

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

Você pode definir tipos de objetos de Realm com classes JavaScript. Para utilizar uma classe como um tipo de objeto, defina o esquema de objeto na propriedade 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",
};
}

Observação

Os nomes das classes têm um limite máximo de 57 caracteres UTF-8.

Passe a própria classe para a propriedade schema do objeto Realm.Configuration ao abrir um domínio. Você pode então ler e gravar dados normalmente.

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

Cada propriedade em um objeto Realm tem um tipo de dados fortemente definido. O tipo de propriedade pode ser um tipo de dados primitivo ou um tipo de objeto definido no mesmo domínio. O tipo também especifica se a propriedade contém um único valor ou uma lista de valores.

O Realm suporta os seguintes tipos de dados primitivos:

  • bool para valores booleanos

  • int e double, que mapeiam para valores JavaScript number

  • Decimal128 para números de alta precisão

  • string

  • date, que mapeia para Data

  • data, que mapeia para ArrayBuffer

  • objectId, que mapeia para ObjectId

Para especificar que um campo contém uma lista de um tipo de valor primitivo, acrescente [] ao nome do tipo.

Para definir uma propriedade para um tipo de objeto, crie um par chave-valor que represente o nome e o tipo de dados da propriedade no campo properties.

O seguinte esquema define um tipo de Car que tem estas propriedades: _id make, model e 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",
};
}

Para marcar uma propriedade como opcional, anexe um ponto de interrogação ? ao seu tipo.

O seguinte esquema Car define uma propriedade miles opcional do 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",
};
}

Para especificar uma propriedade como uma chave primária do tipo de objeto, configure o campo primaryKey do esquema para o nome da propriedade.

Observação

Uma chave primária é uma propriedade que identifica exclusivamente um objeto. O Realm indexa automaticamente as propriedades de chave primária, o que lhe permite ler e modificar objetos com eficiência com base em sua chave primária.

Se um tipo de objeto tiver uma chave primária, todos os objetos desse tipo deverão incluir a propriedade da chave primária com um valor exclusivo entre objetos do mesmo tipo em um domínio. Um tipo de objeto pode ter no máximo uma chave primária. Não é possível alterar a propriedade de chave primária de um tipo de objeto após qualquer objeto desse tipo ser adicionado a um domínio, e não é possível modificar o valor da chave primária de um objeto.

O seguinte esquema de objeto do Car especifica a propriedade _id como sua chave primária.

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",
};
}

O Realm permite a indexação para propriedades de string, inteiros, booleanos, Date, UUID e ObjectId. Para definir um índice para uma determinada propriedade, defina indexed para true.

Observação

Um índice aumenta significativamente a velocidade de certas operações de leitura ao custo de tempos de gravação um pouco mais lentos e sobrecarga adicional de armazenamento e memória. O Realm armazena índices no disco, o que torna seus arquivos de domínio maiores. Toda entrada do índice tem um mínimo de 12 bytes. A ordenação das entradas do índice suporta correspondências de igualdade eficientes e operações de query baseadas em intervalo.

É melhor adicionar índices somente ao otimizar o desempenho de leitura para situações específicas.

O seguinte esquema de objeto do Car define um índice na propriedade _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",
};
}

Além dos índices padrão, o Realm também suporta índices de Pesquisa de Texto Completo (FTS) em propriedades de string. Embora você possa query um campo de string com ou sem um índice padrão, um índice FTS permite pesquisar várias palavras e frases e excluir outras.

Para obter mais informações sobre como fazer queries em índices FTS, consulte Filtrar com Full Text Search.

Para criar um índice FTS, configure o tipo indexado para 'full-text'. Isso permite queries de texto completo na propriedade. No exemplo a seguir, definimos o tipo indexado para a propriedade name como '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?",
},
};
}

Para definir um valor padrão, configure o valor da propriedade para um objeto com um campo type e um campo default.

O seguinte esquema de objeto Car especifica um valor padrão de 0 para a propriedade 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",
};
}

Por padrão, o Realm utiliza o nome definido na classe de modelo para representar classes e campos internamente. Em alguns casos, você pode querer alterar esse comportamento. Por exemplo:

  • Para facilitar o trabalho em plataformas onde as convenções de nomenclatura são diferentes. Por exemplo, se os nomes das propriedades do esquema Device Sync usarem snake case, enquanto seu projeto usa camel case.

  • Para alterar um nome de campo ou classe sem forçar uma migração.

  • Para oferecer suporte a várias classes de modelo com o mesmo nome em pacotes diferentes.

  • Para usar um nome de classe maior que o limite de 57 caracteres imposto pelo Realm.

Você pode mapear uma classe ou nome de propriedade em seu código para um nome diferente para armazenar em um domínio. Se você gravar em um domínio sincronizado, o esquema Sync verá os valores armazenados usando a classe persistente ou o nome da propriedade.

Observe que as migrações devem usar o nome de classe ou propriedade persistente, e quaisquer erros de esquema relatados também usam o nome persistente.

Para usar em seu código um nome de classe diferente do que é armazenado em um domínio:

  1. Defina a propriedade name do esquema do objeto de Realm como o nome que você deseja usar para armazenar o objeto.

  2. Use o nome da classe na propriedade schema da configuração do Realm quando você abrir o domínio.

  3. Use o nome mapeado para executar operações CRUD ou ao definir Inscrições flexible Sync.

No exemplo seguinte, o Realm armazena objetos criados com a classe 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 usar um nome de propriedade diferente no seu código do que é armazenado em um Realm, defina mapTo para o nome da propriedade conforme aparece no seu código.

No esquema de objeto Car a seguir, o Realm armazena o nome do modelo do carro com a propriedade model_name do caso da cobra. O esquema mapeia a propriedade para modelName para objetos utilizados no código do 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",
};
}

Dica

Veja também:

Como alternativa, você pode definir seus relacionamentos no App Services App.

Um relacionamento para-um mapeia uma propriedade para uma instância única de outro tipo de objeto. Por exemplo, pode modelar um fabricante com, no máximo, um automóvel como uma relação entre si.

Para definir uma propriedade de relacionamento entre um, especifique o nome do tipo de objeto relacionado como o tipo de propriedade.

Importante

Relacionamentos um-para-um devem ser opcionais

Quando você declara um relacionamento um-para-um no modelo de objeto, ele deve ser uma propriedade opcional. Se você tentar tornar um relacionamento um-para-um obrigatório, o Realm lançará uma exceção em tempo de execução.

O esquema de objeto Manufacturer a seguir especifica que um fabricante pode ou não fazer um único Car. Se eles fizerem um Car, o Realm vinculará a ele através da propriedade 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?",
},
};
}

Uma relação para-muitos mapeia uma propriedade para zero ou mais instâncias de outro tipo de objeto. Por exemplo, você pode modelar um fabricante com qualquer número de carros como uma relação para-muitos.

Para definir uma propriedade de relacionamento entre muitos, especifique o nome do tipo de objeto relacionado como uma lista.

Um aplicativo poderia usar os seguintes esquemas de objeto para indicar que um Manufacturer pode criar vários objetos Car, incluindo-os em sua propriedade 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?",
},
};
}

Uma propriedade relacionamento inverso é um relacionamento de backlink automático. O Realm atualiza automaticamente os relacionamentos implícitos sempre que um objeto é adicionado ou removido em uma lista de itens correspondentes. Você não pode definir manualmente o valor de uma propriedade de relacionamento inversa.

Para definir uma propriedade de relacionamento inversa, configure o tipo de propriedade para linkingObjects e especifique o tipo de objeto e o nome da propriedade que define o relacionamento para inverter.

Um aplicativo poderia usar os seguintes esquemas de objetos para indicar que um Manufacturer pode criar muitos objetos Car e que cada Car deve controlar automaticamente qual Manufacturer o cria.

  • A propriedade Manufacturer do objeto cars é definida como uma relação entre muitos
    com Car objetos e contém todos os carros de um determinado fabricante.
  • A propriedade Car do objeto assignee inverte a relação e
    atualizações automáticas para referir-se a qualquer objecto Manufacturer que contenha o veículo na sua propriedade 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?",
// 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",
},
},
};
}

Para definir um modelo de objeto de Realm com um objeto incorporado (objeto de Realm aninhado), defina embedded como true.

Existe um objeto incorporado como dados aninhados dentro de um único objeto principal específico. Ele herda o ciclo de vida de seu objeto principal e não pode existir como um objeto de Realm independente. O Realm exclui automaticamente os objetos incorporados se o objeto principal for excluído ou quando for substituído por uma nova instância de objeto incorporado. Objetos incorporados não podem ter uma chave primária.

Você pode referenciar um tipo de objeto incorporado a partir de tipos de objeto principal da mesma maneira que um relacionamento.

O exemplo seguinte exige dois esquemas principais, Manufacturer e Car. O aplicativo requer um esquema secundário incorporado Warranty. Um objeto Manufacturer pode incorporar uma lista de objetos Warranty, enquanto um objeto Car só pode incorporar um ú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",
},
};
}

Alterado na versão 12.2.1.

Se você estiver utilizando o Flexible Sync e precisar sincronizar uma coleção de forma unidirecional do seu dispositivo para o seu banco de dados do Atlas, configure a propriedade asymmetric no seu esquema de objetos.

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",
},
};
}

Nas versões 12.2.0 e anteriores do SDK do Node.js, não é possível criar vínculos de objetos assimétricos a tipos Realm.Object. Nas versões 12.2.1 e posteriores do SDK, objetos assimétricos podem se vincular a tipos Realm.Object , além de objetos embarcados.

Observação

Tentando ler objetos assimétricos

Objetos assimétricos não podem ser lidos. Se você tentar executar uma query de um objeto assimétrico, receberá o seguinte erro: "Erro: Não é possível executar uma query de classes assimétricas.".

Para saber mais sobre a ingestão de dados, leia Otimizar a sincronização com a ingestão de dados.

Novidades na versão 12.9.0.

A partir da versão 12 do SDK do Node.js.9.0, você pode armazenar collections de dados mistos dentro de uma propriedade mixed . Você pode usar esse recurso para modelar estruturas de dados complexas, como documentos JSON ou MongoDB, sem precisar definir um modelo de dados rigoroso.

Dados não estruturados são dados que não estão em conformidade com facilmente um esquema esperado, tornando difícil ou impraticável modelar classes de dados individuais. Por exemplo, seu aplicativo pode ter dados altamente variáveis ou dados dinâmicos cuja estrutura é desconhecida no tempo de execução.

O armazenamento de coleções em uma propriedade mista oferece flexibilidade sem sacrificar a funcionalidade, incluindo a sincronização de desempenho ao usar o Device Sync. E você pode trabalhar com eles da mesma forma que faria com uma collection não mista:

  • Você pode aninhar collections mistas em até 100 níveis.

  • Você pode consultar e reagir a alterações em coleções mistas.

  • Você pode localizar e atualizar elementos individuais de coleção mista.

No entanto, armazenar dados em coleções mistas é menos eficiente do que usar um esquema estruturado ou serializar blobs JSON em uma única propriedade de string.

Para modelar dados não estruturados em seu aplicativo, defina as propriedades apropriadas em seu esquema como tipos mistos . Você pode então definir essas propriedades mixed como uma lista ou uma coleção de dicionário de elementos mistos. Observe que mixed não pode representar um conjunto ou um objeto embarcado.

Dica

  • Use um mapa de tipos de dados mistos quando o tipo for desconhecido, mas cada valor terá um identificador exclusivo.

  • Use uma lista de tipos de dados mistos quando o tipo for desconhecido, mas a ordem dos objetos for significativa.

Voltar

Dados do modelo

Próximo

Relacionamentos e objetos incorporados