Element Operators
Learn how to query documents based on whether a field exists or what type it is using $exists and $type.
Element Operators
So far, every operator we used filters documents based on the value of a field. Element operators are different — they filter documents based on the field itself.
$exists— does this field exist in the document?$type— what data type is this field?
These are especially useful in MongoDB because documents in the same collection can have different fields and different types.
$exists
$exists matches documents where a field either exists or does not exist. Pass true to find documents that have the field, and false to find documents that do not.
Syntax
db.collection.find({ field: { $exists: true } })
db.collection.find({ field: { $exists: false } })Example — Find students who have a phone number
Not every student document has a phone field. $exists lets you find only the ones that do:
db.students.find({ phone: { $exists: true } })Example — Find students who do NOT have a phone number
db.students.find({ phone: { $exists: false } })Example — Find students who have a graduationDate set
db.students.find({ graduationDate: { $exists: true } })$exists with null
There is an important difference between a field not existing and a field being null:
// Document A — field does not exist
{ name: "Ali Hassan", age: 16 }
// Document B — field exists but is null
{ name: "Sara Ahmed", age: 15, graduationDate: null }// $exists: true matches Document B but NOT Document A
db.students.find({ graduationDate: { $exists: true } })
// $exists: false matches Document A but NOT Document B
db.students.find({ graduationDate: { $exists: false } })$exists: true matches any document where the field is present — even if its value is null.
In a real school system, you will often have fields that only some documents have — like transferredFrom, graduationDate, or scholarshipAmount. Use $exists to find documents that have or are missing these optional fields.
Combining $exists with Other Operators
You can combine $exists with other operators to be more precise:
// Students who have a phone number AND are enrolled
db.students.find({
phone: { $exists: true },
enrolled: true
})
// Students who are missing an address field
db.students.find({
address: { $exists: false }
})$type
$type matches documents where a field is a specific BSON data type. This is useful when your collection has inconsistent data — for example, some documents store age as a number and others accidentally stored it as a string.
Syntax
You can pass either the BSON type name as a string or its numeric code:
db.collection.find({ field: { $type: "string" } })
db.collection.find({ field: { $type: 2 } }) // 2 is the code for stringUsing the string name is cleaner and easier to read.
Common BSON type names
| Type | String alias | Number code |
|---|---|---|
| Double | "double" | 1 |
| String | "string" | 2 |
| Object | "object" | 3 |
| Array | "array" | 4 |
| Boolean | "bool" | 8 |
| Date | "date" | 9 |
| Null | "null" | 10 |
| Integer (32-bit) | "int" | 16 |
| Integer (64-bit) | "long" | 18 |
| ObjectId | "objectId" | 7 |
Example — Find students where age is stored as a string
Someone accidentally inserted age as a string instead of a number. Find those documents:
db.students.find({ age: { $type: "string" } })Now you know which documents need fixing.
Example — Find students where age is stored as a number
db.students.find({ age: { $type: "double" } })Example — Find students where subjects is actually an array
db.students.find({ subjects: { $type: "array" } })Example — Find documents where enrollmentDate is a real Date type
db.students.find({ enrollmentDate: { $type: "date" } })This is useful to catch documents where someone stored the date as a string instead of a proper Date object.
$type with Multiple Types
You can pass an array of types to match documents where a field is any one of those types:
// Find students where age is stored as either int or double
db.students.find({
age: { $type: ["int", "double"] }
})Practical Use — Cleaning Inconsistent Data
The most common real-world use of $type is finding and fixing data quality issues. In our school system, imagine someone inserted some students with age as a string:
// Step 1 — find the bad documents
db.students.find({ age: { $type: "string" } })// Step 2 — you now know which ones to fix
// Fix them one by one or write a script to convert themIf your collection has mixed types in the same field — some documents storing age as a number and others as a string — comparison operators like $gt and $lt will not work correctly on the string documents. Always make sure fields have consistent types across all documents.
Combining $exists and $type
You can use both together for precise field checks:
// Students who have a graduationDate AND it is a proper Date type
db.students.find({
graduationDate: {
$exists: true,
$type: "date"
}
})
// Students who have an age field AND it is stored as a number
db.students.find({
age: {
$exists: true,
$type: "double"
}
})School System Examples
// Find students who have a guardian field set
db.students.find({ guardian: { $exists: true } })
// Find students missing an address
db.students.find({ address: { $exists: false } })
// Find teachers who have a contactNumber field
db.teachers.find({ contactNumber: { $exists: true } })
// Find any student where age was accidentally stored as a string
db.students.find({ age: { $type: "string" } })
// Find students where subjects is an array
db.students.find({ subjects: { $type: "array" } })
// Find students who have a graduationDate that is a real Date
db.students.find({
graduationDate: {
$exists: true,
$type: "date"
}
})
// Find documents where address is an embedded object
db.students.find({ address: { $type: "object" } })Quick Reference
| Operator | What it does | Example |
|---|---|---|
$exists: true | Field exists in the document | { phone: { $exists: true } } |
$exists: false | Field does not exist | { phone: { $exists: false } } |
$type: "string" | Field is a string | { age: { $type: "string" } } |
$type: "double" | Field is a number | { age: { $type: "double" } } |
$type: "date" | Field is a Date | { dob: { $type: "date" } } |
$type: "array" | Field is an array | { subjects: { $type: "array" } } |
Use $exists and $type during data audits — before you add validation rules, run these queries to check how consistent your existing data is. You will often find surprising things — missing fields, wrong types, null values where you expected real data.