Join us Sept 17 at .local NYC! Use code WEB50 to save 50% on tickets. Learn more >
MongoDB Event
Menu Docs
Página inicial do Docs
/
Manual do banco de dados
/ /

Especificar validação para coleções polimórficas

Você pode especificar a validação de esquema para uma coleção que armazena dados polimórficos ou documentos com estruturas ou esquemas variáveis.

Para criar validação de esquema para vários esquemas em uma única collection, você pode definir os esquemas em suas regras de validação e garantir que os documentos estejam em conformidade com um dos esquemas da sua collection.

Considere uma coleção, accounts, que armazena dados sobre clientes de um banco e os detalhes de suas contas. A coleção contém documentos customer e documentos account .

O código a seguir insere dois documentos customer na coleção accounts para armazenar os detalhes dos clientes Andre e Ana, respectivamente. Ele também insere dois documentos account para representar cada uma de suas contas de economia individuais e um terceiro documento account para representar sua conta atual compartilhada. Você pode executar o código para este tutorial nashell do MongoDB (mongosh).

db.accounts.insertMany( [
{
"customerId": "CUST-123456789",
"docType": "customer",
"name": {
"title": "Mr",
"first": "Andrew",
"middle": "James",
"last": "Morgan"
},
"address": {
"street1": "240 Blackfriars Rd",
"city": "London",
"postCode": "SE1 8NW",
"country": "UK"
},
"customerSince": ISODate("2005-05-20")
},
{
"customerId": "CUST-987654321",
"docType": "customer",
"name": {
"title": "Mrs",
"first": "Anne",
"last": "Morgan"
},
"address": {
"street1": "240 Blackfriars Rd",
"city": "London",
"postCode": "SE1 8NW",
"country": "UK"
},
"customerSince": ISODate("2003-12-01")
},
{
"accountNumber": "ACC1000000654",
"docType": "account",
"accountType": "checking",
"customerId": [
"CUST-123456789",
"CUST-987654321"
],
"dateOpened": ISODate("2003-12-01"),
"balance": Decimal128("5067.65")
},
{
"accountNumber": "ACC1000000432",
"docType": "account",
"accountType": "savings",
"customerId": [
"CUST-123456789"
],
"dateOpened": ISODate("2005-10-28"),
"balance": Decimal128("10341.21")
},
{
"accountNumber": "ACC1000000890",
"docType": "account",
"accountType": "savings",
"customerId": [
"CUST-987654321"
],
"dateOpened": ISODate("2003-12-15"),
"balance": Decimal128("10341.89")
}
] );

Para permitir somente documentos que sigam os esquemas customer ou account na coleção accounts, configure a validação de esquema usando o procedimento a seguir.

1

Para distinguir entre diferentes tipos de documentos, você pode utilizar vários JSON schemas. Para definir quais atributos devem estar em um documento e quais tipos de dados eles aceitam, crie dois esquemas: um para um documento do customer e outro para um documento do account. Cada esquema inclui um atributo docType para identificar qual tipo de entidade ele representa.

const customerSchema = {
required: ["docType", "customerId", "name", "customerSince"],
properties: {
docType: { enum: ["customer"] },
customerId: { bsonType: "string"},
name: {
bsonType: "object",
required: ["first", "last"],
properties: {
title: { enum: ["Mr", "Mrs", "Ms", "Dr"]},
first: { bsonType: "string" },
middle: { bsonType: "string" },
last: { bsonType: "string" }
}
},
address: {
bsonType: "object",
required: ["street1", "city", "postCode", "country"],
properties: {
street1: { bsonType: "string" },
street2: { bsonType: "string" },
postCode: { bsonType: "string" },
country: { bsonType: "string" }
}
},
customerSince: {
bsonType: "date"
}
}
};
const accountSchema = {
required: ["docType", "accountNumber", "accountType", "customerId", "dateOpened", "balance"],
properties: {
docType: { enum: ["account"] },
accountNumber: { bsonType: "string" },
accountType: { enum: ["checking", "savings", "mortgage", "loan"] },
customerId: { bsonType: "array" },
dateOpened: { bsonType: "date" },
balance: { bsonType: "decimal" }
}
};
2

Para permitir documentos que correspondam a customerSchema ou a accountSchema, use o operador de JSON schema oneOf. Em seguida, use o comando collMod para atualizar a collection accounts a ser usada para sua validação de esquema.

db.runCommand({
collMod: "accounts",
validator: { $jsonSchema: { oneOf: [ customerSchema, accountSchema ] } }
})
3

Opcionalmente, você pode adicionar validações semânticas extras. Por exemplo, você pode adicionar as seguintes restrições aos documentos da sua collection:

  • Para documentos customer, o valor customerSince não pode ser anterior ao horário atual.

  • Para documentos account, o valor dateOpened não pode ser anterior ao horário atual.

  • Para contas de economia, o balance não pode cair abaixo de zero.

Você pode implementar as validações extras identificando documentos customer e account inválidos e implementando essas restrições na validação de esquema.

const invalidCustomer = {
"$expr": { "$gt": ["$customerSince", "$$NOW"] }
};
const invalidAccount = {
$or: [
{
accountType: "savings",
balance: { $lt: 0}
},
{
"$expr": { "$gt": ["$dateOpened", "$$NOW"]}
}
]
};
const schemaValidation = {
"$and": [
{ $jsonSchema: { oneOf: [ customerSchema, accountSchema ] }},
{ $nor: [
invalidCustomer,
invalidAccount
]
}
]
};
db.runCommand({
collMod: "accounts",
validator: schemaValidation
})
4

Para verificar se todos os documentos que já estão na sua coleção estão de acordo com a nova validação de esquema, use o comando db.collection.validate().

db.accounts.validate()
{
ns: '66cf8508e64dbb03ce45b30e_test.accounts',
uuid: UUID('1aedf62a-f202-4e7c-b434-879057bb6d6b'),
nInvalidDocuments: 0,
nNonCompliantDocuments: 0,
nrecords: 10,
nIndexes: 1,
keysPerIndex: { _id_: 10 },
indexDetails: { _id_: { valid: true } },
valid: true,
repaired: false,
readTimestamp: Timestamp({ t: 1749235730, i: 26 }),
warnings: [],
errors: [],
extraIndexEntries: [],
missingIndexEntries: [],
corruptRecords: [],
ok: 1,
'$clusterTime': {
clusterTime: Timestamp({ t: 1749235753, i: 31 }),
signature: {
hash: Binary.createFromBase64('3h7qyhLsgU21Pnzf/KVLl8suu2I=', 0),
keyId: Long('7449048397505364002')
}
},
operationTime: Timestamp({ t: 1749235753, i: 31 })
}

nNonCompliantDocuments: 0 na saída indica que todos os documentos na collection accounts estão em conformidade com os esquemas da collection.

5

Para verificar a validação de esquema, você pode tentar inserir um documento inválido na coleção accounts. Por exemplo, tente inserir um documento customer sem o campo last obrigatório, para sobrenome:

db.accounts.insertOne(
{
"docType": "customer",
"customerId": "12345",
"name": {
"first": "John",
},
"customerSince": "2025-01-01T00:00:00Z"
}
)
MongoServerError: Document failed validation

Voltar

Consultar e modificar

Nesta página