Elementoperatoren und Typprüfungen
Fragen Sie mit $exists und $type ab, ob ein Feld vorhanden ist oder welchen Typ es hat, um optionale Daten oder Daten mit gemischten Typen zu verarbeiten.
Elementoperatoren und Typprüfungen ist eine kostenlose MongoDB Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des MongoDB Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der MongoDB Academy-Kurs umfasst insgesamt 4 Lektionen.
Optionale Felder in flexiblen Schemata
Das flexible Schema von MongoDB bedeutet, dass einige Dokumente in einer Collection Felder enthalten können, die anderen fehlen. Ein Benutzerdokument könnte beispielsweise ein optionales Feld phoneNumber enthalten – einige Benutzer haben es angegeben, andere nicht. In SQL würden Sie dies mit einem NULL-Wert in jeder Zeile behandeln. In MongoDB ist das Feld in einigen Dokumenten einfach nicht vorhanden.
Dieser Unterschied hat wichtige Auswirkungen auf Abfragen. Die Elementoperatoren von MongoDB – hauptsächlich $exists und $type – ermöglichen Abfragen anhand des Vorhandenseins oder des Typs eines Feldes statt anhand seines Werts.
$exists: Vorhandensein eines Feldes prüfen
$exists: true findet Dokumente, die das angegebene Feld enthalten (unabhängig von seinem Wert, auch wenn dieser null ist). $exists: false findet Dokumente, in denen das Feld vollständig fehlt.
Dieser Unterschied ist subtil, aber wichtig: Ein Dokument mit { phone: null } erfüllt die Bedingung { phone: { $exists: true } }, weil das Feld vorhanden ist – sein Wert ist lediglich null. Nur ein Dokument, das überhaupt kein Feld phone enthält, erfüllt { 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 } });Abfragen für null und fehlende Felder
Der Gleichheitsfilter von MongoDB mit null weist ein Verhalten mit zwei möglichen Ergebnissen auf, das Anfänger oft überrascht: { phone: null } findet Dokumente, in denen phone ausdrücklich null ist, UND Dokumente, in denen phone überhaupt nicht vorhanden ist. Der Grund ist, dass MongoDB ein fehlendes Feld bei Gleichheitsvergleichen implizit als null betrachtet.
Wenn Sie zwischen „Feld ist null“ und „Feld fehlt“ unterscheiden möchten, kombinieren Sie $exists mit $eq: null. Für die meisten praktischen Zwecke bedeuten beide Fälle „keine Telefonnummer angegeben“, und Sie können sie gleich behandeln.
// 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: Nach BSON-Typ abfragen
MongoDB ist schemaflexibel. Das bedeutet, dass ein Feld wie price in den meisten Dokumenten ein Number-Wert sein kann, in einigen älteren Datensätzen aber versehentlich als String gespeichert wurde. Mit dem Operator $type können Sie Dokumente anhand des BSON-Typs des Feldwerts filtern.
Sie können Typen anhand ihres Namens (z. B. 'string', 'int', 'date') oder anhand ihrer BSON-Typnummer (z. B. 2 für String, 16 für Int32) angeben. Die Verwendung von Typnamen ist lesbarer und wird empfohlen.
// 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' } });Gebräuchliche BSON-Typnamen
Die am häufigsten verwendeten BSON-Typnamen für $type-Abfragen sind:
'double'– 64-Bit-Gleitkommazahl (Standardzahlentyp in JS)'string'– UTF-8-Zeichenfolge'object'– eingebettetes Dokument (Unterobjekt)'array'– Array'binData'– Binärdaten'objectId'– ObjectId'bool'– boolescher Wert'date'– Datum'null'– Nullwert'int'– 32-Bit-Ganzzahl'long'– 64-Bit-Ganzzahl'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 _idsDer Alias „number“
Eine nützliche Abkürzung ist der Typalias 'number', der jeden numerischen BSON-Typ findet: double, int, long und decimal. Dies entspricht der Angabe eines Arrays mit allen vier numerischen Typnamen, ist aber deutlich übersichtlicher.
Verwenden Sie 'number', wenn Sie alle Dokumente finden möchten, in denen ein Feld eine beliebige Art von Zahl enthält, unabhängig von der jeweiligen Genauigkeit. Das ist besonders nützlich für Prüfungen der Datenqualität, bei denen Sie Felder identifizieren möchten, die numerisch sein sollten, aber versehentlich als Zeichenfolgen gespeichert wurden.
// '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) } }
);
});$exists bei Schema迁移 verwenden
Bei Schema迁移 in MongoDB werden bestehenden Dokumenten häufig neue Pflichtfelder hinzugefügt. Mit $exists finden Sie Dokumente, die noch aktualisiert werden müssen – oder bereits migriert wurden.
Ein typischer Migrationsablauf: Verwenden Sie zunächst { newField: { $exists: false } }, um alle älteren Dokumente zu finden, und fügen Sie anschließend das neue Feld mit einem Standardwert hinzu. Überprüfen Sie den Fortschritt, indem Sie zählen, wie viele Dokumente noch $exists: false erfüllen. Dieser schrittweise Migrationsansatz funktioniert ohne Ausfallzeit, da das flexible Schema von MongoDB ermöglicht, dass alte und neue Dokumentstrukturen vorübergehend nebeneinander bestehen.
// 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);
}$exists und $type kombinieren
Sie können $exists und $type in einer Abfrage kombinieren, um Dokumente zu finden, in denen ein Feld vorhanden ist UND einen bestimmten Typ hat. Das ist bei Prüfungen der Datenqualität nützlich, wenn Sie Dokumente mit einem falschen Feldtyp von Dokumenten unterscheiden möchten, in denen das Feld schlicht fehlt.
In einer Collection, in der age eine Zahl sein sollte, könnten Sie beispielsweise getrennt zählen: (1) Dokumente, in denen das Feld age vollständig fehlt, (2) Dokumente, in denen age eine Zeichenfolge ist (Dateneingabefehler), und (3) Dokumente, in denen age eine gültige Zahl ist.
// 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: Feldübergreifende Vergleiche
Mit dem Operator $expr können Sie Aggregationsausdrücke innerhalb eines regulären find()-Filters verwenden. Dadurch werden Vergleiche zwischen Feldern möglich – etwas, das mit den standardmäßigen Abfrageoperatoren nicht möglich ist.
Beispiel: „Finde Bestellungen, bei denen der Rabatt größer als 50 % des ursprünglichen Preises ist“ erfordert den Vergleich von discount mit einem berechneten Anteil von originalPrice – also zweier Felder im selben Dokument. $expr ermöglicht solche Beziehungen mithilfe von Ausdrucksoperatoren wie $gt, $multiply und $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'] }
});Indizierung für $exists-Abfragen
Abfragen mit $exists werden von Indizes unterschiedlich unterstützt. Ein Index für ein Feld hilft bei { field: { $exists: false } } nicht weiter – wenn das Feld fehlt, ist es nicht im Index enthalten –, daher muss MongoDB jedes Dokument durchsuchen. { field: { $exists: true } } kann jedoch einen Sparse-Index verwenden: Ein Sparse-Index speichert nur Einträge für Dokumente, die das indizierte Feld enthalten, und ermöglicht so schnelle Suchen nach vorhandenen Dokumenten.
Verwenden Sie db.collection.createIndex({ field: 1 }, { sparse: true }), um einen Sparse-Index zu erstellen, wenn Sie häufig nach Dokumenten suchen, die ein optionales Feld enthalten.
// 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 queriesWorkflow für die Datenqualitätsprüfung
Ein praktischer Workflow für die Datenqualitätsprüfung mit und sieht folgendermaßen aus: Identifizieren Sie zunächst alle unterschiedlichen Feldmuster in Ihrer Collection, um Inkonsistenzen zu erkennen. Kategorisieren Sie anschließend die Dokumente nach ihren Feldtypen und schreiben Sie schließlich gezielte updateMany-Aufrufe, um die Daten zu normalisieren.
Die Aggregationspipeline von MongoDB erleichtert die Prüfung: nach eines Feldes, um zu zählen, wie viele Dokumente jeweils jeden Typ enthalten. So erhalten Sie ein klares Bild der Datenqualitätsprobleme, bevor Sie mit deren Behebung beginnen.
// 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!Schnelltest
Testen Sie Ihr Verständnis der Konzepte zu MongoDB & NoSQL-Datenbanken aus dieser Lektion.
Zusammenfassung der Lektion
In dieser Lektion haben Sie Folgendes gelernt: Mit $exists-Abfragen können Sie prüfen, ob ein Feld vorhanden ist oder fehlt – ein fehlendes Feld und ein Feld mit dem Wert null sind unterschiedlich und lassen sich durch die Kombination von $exists: true mit $ne: null unterscheiden. $type filtert nach dem BSON-Typnamen (String, Zahl, Datum, Array usw.) und ist für Datenqualitätsprüfungen in schemaflexiblen Collections unverzichtbar. Sparse-Indizes unterstützen $exists: true-Abfragen für optionale Felder effizient, da nur Dokumente indiziert werden, die das Feld enthalten. Als Nächstes sehen wir uns Regex-Abfragen und Mustervergleiche für flexible Textsuchen an.
Lerne JavaScript mit einem KI-Tutor — kostenlos
Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.
- Kurse
- 30
- Lektionen
- 120
Häufig gestellte Fragen
Ist die Lektion „Elementoperatoren und Typprüfungen“ kostenlos?
Ja — der vollständige Text von „Elementoperatoren und Typprüfungen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des MongoDB Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der MongoDB Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Elementoperatoren und Typprüfungen“?
Fragen Sie mit $exists und $type ab, ob ein Feld vorhanden ist oder welchen Typ es hat, um optionale Daten oder Daten mit gemischten Typen zu verarbeiten. Du übst MongoDB Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um MongoDB Academy zu starten?
Keine Vorkenntnisse erforderlich. MongoDB Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „Elementoperatoren und Typprüfungen“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser MongoDB Academy-Lektion Code schreiben und ausführen?
Ja. Jede MongoDB Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Vergleichsoperatoren: $eq, $gt, $lt, $in
- Logische Operatoren: $and, $or, $nor, $not
- Elementoperatoren und Typprüfungen
- Regex-Abfragen und Mustersuche