Operadores de elementos e verificações de tipo
Consulte a presença ou o tipo de um campo usando $exists e $type para lidar com dados opcionais ou de tipos variados.
Operadores de elementos e verificações de tipo é uma aula grátis de MongoDB Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de MongoDB Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de MongoDB Academy inclui 4 aulas no total.
Campos opcionais em esquemas flexíveis
O esquema flexível do MongoDB significa que alguns documentos de uma coleção podem ter campos que outros não têm. Um documento de usuário pode ter um campo opcional phoneNumber — alguns usuários o forneceram, outros não. No SQL, você lidaria com isso usando um valor NULL em cada linha. No MongoDB, o campo simplesmente não existe em alguns documentos.
Essa diferença tem implicações importantes para as consultas. Os operadores de elementos do MongoDB — principalmente $exists e $type — permitem consultar com base na presença ou no tipo de um campo, em vez de consultar seu valor.
$exists: verificando a presença de um campo
$exists: true encontra documentos que têm o campo especificado (independentemente de seu valor, mesmo que o valor seja null). $exists: false encontra documentos nos quais o campo está completamente ausente.
Essa distinção é sutil, mas importante: um documento com { phone: null } corresponde a { phone: { $exists: true } } porque o campo existe — ele apenas tem valor nulo. Somente um documento sem nenhum campo phone corresponde a { phone: { $exists: false } }.
// Find users who have provided a phone number (field exists)
db.users.find({ phone: { $exists: true } });
// Find users who never provided a phone number (field absent)
db.users.find({ phone: { $exists: false } });
// Key distinction:
// { phone: null } => $exists: true (field exists, value is null)
// { name: 'Alice' } => $exists: false (no phone field at all)
// Combined: field exists AND is not null
db.users.find({ phone: { $exists: true, $ne: null } });Consultas de campo nulo versus ausente
O filtro de igualdade do MongoDB com null tem um comportamento duplo que costuma surpreender iniciantes: { phone: null } encontra documentos nos quais phone é explicitamente null E documentos nos quais phone não existe. Isso acontece porque o MongoDB considera implicitamente nulo um campo ausente em comparações de igualdade.
Se quiser distinguir entre “o campo é nulo” e “o campo está ausente”, combine $exists com $eq: null. Para a maioria das finalidades práticas, ambos os casos significam “nenhum número de telefone foi fornecido”, e você pode tratá-los da mesma forma.
// Matches BOTH null and missing field:
db.users.find({ phone: null });
// Returns: { name: 'Alice', phone: null }
// AND: { name: 'Bob' } (no phone field)
// Only where field is explicitly null:
db.users.find({ phone: { $eq: null, $exists: true } });
// Returns: { name: 'Alice', phone: null }
// NOT: { name: 'Bob' } (missing field)
// Only where field is missing:
db.users.find({ phone: { $exists: false } });$type: consultando pelo tipo BSON
O MongoDB é flexível quanto ao esquema, o que significa que um campo como price pode ser um Number na maioria dos documentos, mas ter sido armazenado acidentalmente como uma String em alguns registros antigos. O operador $type permite filtrar documentos com base no tipo BSON do valor de um campo.
Você pode especificar os tipos pelo nome (por exemplo, 'string', 'int', 'date') ou pelo número do tipo BSON (por exemplo, 2 para String e 16 para Int32). Usar nomes de tipos é mais legível e recomendado.
// Find documents where price is a string (data quality issue)
db.products.find({ price: { $type: 'string' } });
// These need to be fixed - price should be a number
// Find documents where price is a number (any numeric type)
db.products.find({ price: { $type: ['double', 'int', 'long', 'decimal'] } });
// $type accepts an array - matches any of the listed types
// Check for boolean
db.settings.find({ enabled: { $type: 'bool' } });Nomes comuns de tipos BSON
Os nomes de tipos BSON mais usados em consultas com $type são:
'double'— número de ponto flutuante de 64 bits (número padrão do JS)'string'— string UTF-8'object'— documento incorporado (subobjeto)'array'— matriz'binData'— dados binários'objectId'— ObjectId'bool'— booleano'date'— data'null'— valor nulo'int'— inteiro de 32 bits'long'— inteiro de 64 bits'decimal'— Decimal128
// Real-world use: find documents where tags is an array
db.products.find({ tags: { $type: 'array' } });
// Find docs where createdAt is a date (not a string)
db.events.find({ createdAt: { $type: 'date' } });
// Audit: find any document where _id is not an ObjectId
db.users.find({ _id: { $not: { $type: 'objectId' } } });
// These might be docs with custom string _idsO alias 'number'
Um atalho útil é o alias de tipo 'number', que corresponde a qualquer tipo numérico BSON: double, int, long e decimal. Isso equivale a escrever uma matriz com os quatro nomes de tipos numéricos, mas é muito mais limpo.
Use 'number' quando quiser encontrar todos os documentos nos quais um campo seja de qualquer tipo numérico, independentemente da precisão específica. Isso é particularmente útil em verificações de qualidade de dados nas quais você deseja identificar campos que deveriam ser numéricos, mas foram armazenados acidentalmente como strings.
// 'number' alias matches double, int, long, decimal
db.products.find({ price: { $type: 'number' } });
// Same as: { price: { $type: ['double', 'int', 'long', 'decimal'] } }
// Data quality check: find price fields that are strings
// These should be numbers:
db.products.find({ price: { $type: 'string' } });
// Fix those docs:
db.products.find({ price: { $type: 'string' } }).forEach(doc => {
db.products.updateOne(
{ _id: doc._id },
{ $set: { price: parseFloat(doc.price) } }
);
});Usando $exists em migrações de esquema
As migrações de esquema no MongoDB geralmente envolvem adicionar novos campos obrigatórios a documentos existentes. $exists ajuda a encontrar os documentos que ainda precisam ser atualizados — ou que já foram migrados.
Um fluxo de migração típico: primeiro use { newField: { $exists: false } } para encontrar todos os documentos antigos e, em seguida, adicione o novo campo com um valor padrão. Verifique o progresso contando quantos documentos ainda têm $exists: false. Essa abordagem de migração gradual funciona sem tempo de inatividade, pois o esquema flexível do MongoDB permite que formatos antigos e novos de documentos coexistam temporariamente.
// Migration: add 'timezone' field with default value to legacy users
async function migrateTimezone() {
const batchSize = 1000;
let processed = 0;
while (true) {
const result = await db.collection('users').updateMany(
{ timezone: { $exists: false } }, // Legacy docs without field
{ $set: { timezone: 'UTC' } }, // Add default
{ limit: batchSize } // Process in batches
);
processed += result.modifiedCount;
if (result.modifiedCount === 0) break;
}
console.log('Migrated:', processed);
}Combinando $exists e $type
Você pode combinar $exists e $type em uma única consulta para encontrar documentos nos quais um campo existe E tem um tipo específico. Isso é útil em auditorias de qualidade de dados nas quais você deseja identificar documentos cujo campo tem o tipo incorreto, em vez de documentos nos quais o campo está simplesmente ausente.
Por exemplo, em uma coleção na qual age deveria ser um número, talvez você queira contar separadamente: (1) documentos nos quais o campo de idade está completamente ausente; (2) documentos nos quais age é uma string (erro de entrada de dados); e (3) documentos nos quais age é um número válido.
// Audit 'age' field data quality
const total = await db.collection('users').countDocuments({});
const missingAge = await db.collection('users')
.countDocuments({ age: { $exists: false } });
const ageIsString = await db.collection('users')
.countDocuments({ age: { $type: 'string' } });
const ageIsNumber = await db.collection('users')
.countDocuments({ age: { $type: 'number' } });
console.log(`Total: ${total}, Missing: ${missingAge}, String: ${ageIsString}, Number: ${ageIsNumber}`);$expr: comparações entre campos
O operador $expr permite usar expressões de agregação dentro de um filtro find() comum. Isso possibilita comparações entre campos — algo que não é possível com operadores de consulta padrão.
Por exemplo: “encontrar pedidos em que o desconto seja maior que 50% do preço original” exige comparar discount com uma fração calculada de originalPrice — dois campos do mesmo documento. O $expr permite essas relações usando operadores de expressão como $gt, $multiply e $divide.
// Find products where salePrice < originalPrice * 0.7 (>30% off)
db.products.find({
$expr: {
$lt: [
'$salePrice',
{ $multiply: ['$originalPrice', 0.7] }
]
}
});
// Find orders where quantity ordered > quantity in stock
db.orders.find({
$expr: { $gt: ['$quantityOrdered', '$quantityInStock'] }
});Indexação para consultas com $exists
As consultas que usam $exists têm suporte de índice limitado. Um índice em um campo não ajuda com { field: { $exists: false } } — se o campo estiver ausente, ele não estará no índice —, portanto o MongoDB precisará verificar todos os documentos. No entanto, { field: { $exists: true } } pode usar um índice esparso: um índice esparso armazena apenas entradas de documentos que possuem o campo indexado, permitindo localizar rapidamente os documentos existentes.
Use db.collection.createIndex({ field: 1 }, { sparse: true }) para criar um índice esparso quando consultar com frequência documentos que possuem um campo opcional.
// Sparse index: only indexes docs where 'proSubscriptionId' exists
db.users.createIndex(
{ proSubscriptionId: 1 },
{ sparse: true }
);
// This query now uses the sparse index efficiently:
db.users.find({ proSubscriptionId: { $exists: true } });
// Only pro subscribers are in the index
// Regular (non-sparse) index would include null entries for all users
// Sparse index is smaller and faster for optional-field queriesFluxo de auditoria da qualidade dos dados
Um fluxo prático de auditoria da qualidade dos dados usando e : primeiro identifique todos os padrões distintos de campos na sua collection para detectar inconsistências; depois, categorize os documentos pelos tipos de seus campos; por fim, escreva chamadas direcionadas de updateMany para normalizar os dados.
O pipeline de agregação do MongoDB facilita a auditoria: por de um campo para contar quantos documentos têm cada tipo. Isso oferece uma visão clara dos problemas de qualidade dos dados antes que você comece a corrigi-los.
// Audit: how many docs have price as each type?
db.products.aggregate([
{
: {
_id: { : '' }, // Group by BSON type of price
count: { : 1 }
}
}
]);
// Results like:
// [{ _id: 'double', count: 4820 },
// { _id: 'string', count: 3 },
// { _id: 'missing', count: 12 }]
// Now you know exactly what to fix!Verificação rápida
test sua compreensão dos conceitos de MongoDB e bancos de dados NoSQL desta lição.
Recapitulação da lição
Nesta lição, você aprendeu: consultas $exists para verificar a presença ou ausência de um campo — um campo ausente e um campo nulo são diferentes e podem ser distinguidos combinando $exists: true com $ne: null; filtros $type por nome do tipo BSON (string, número, data, matriz etc.), essenciais para auditorias de qualidade dos dados em collections com esquema flexível; e índices esparsos, que oferecem suporte eficiente a consultas $exists: true em campos opcionais ao indexar apenas documentos que possuem o campo. A seguir, exploraremos consultas com expressões regulares e correspondência de padrões para pesquisas de texto flexíveis.
Aprenda JavaScript com um tutor de IA — grátis
Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.
- Cursos
- 30
- Aulas
- 120
Perguntas Frequentes
A aula “Operadores de elementos e verificações de tipo” é grátis?
Sim — o texto completo de “Operadores de elementos e verificações de tipo” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de MongoDB Academy, atualize para CoddyKit PRO. O curso de MongoDB Academy inclui 4 aulas no total.
O que vou aprender em “Operadores de elementos e verificações de tipo”?
Consulte a presença ou o tipo de um campo usando $exists e $type para lidar com dados opcionais ou de tipos variados. Você pratica MongoDB Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar MongoDB Academy?
Nenhuma experiência prévia é necessária. MongoDB Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Operadores de elementos e verificações de tipo”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de MongoDB Academy?
Sim. Cada aula de MongoDB Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Operadores de comparação: $eq, $gt, $lt, $in
- Operadores lógicos: $and, $or, $nor, $not
- Operadores de elementos e verificações de tipo
- Consultas com expressões regulares e correspondência de padrões