Edge Case 1: { field: null } vs { field: { $exists: false } }
This is the most critical distinction to memorise. The two queries have completely different semantics.
db.users.find({ phone: null })
db.users.find({ phone: { $exists: false } })
db.users.find({ phone: { $exists: true, $type: "null" } })
Edge Case 2: $type on an Array Field
$type: "array" checks whether the field value itself is an array — it does NOT check the types of elements inside the array.
db.posts.find({ tags: { $type: "array" } })
db.posts.find({ tags: { $elemMatch: { $type: "string" } } })
Edge Case 3: "number" Alias Covers Four Types
db.products.find({ price: { $type: "number" } })
Edge Case 4: $exists with Dot Notation on Nested Fields
db.users.find({ "address.city": { $exists: true } })
db.users.find({ "preferences.notifications.email": { $exists: true } })
db.orders.find({
"shipping.estimatedDelivery": {
$exists: true,
$type: "date"
}
})
Edge Case 5: Wrong Alias Throws an Error
ERROR
Using an unrecognised type alias in $type throws a BadValue error. Common mistakes include using "integer" instead of "int", "boolean" instead of "bool", or "objectid" (wrong case) instead of "objectId".
db.col.find({ field: { $type: "integer" } })
db.col.find({ field: { $type: "boolean" } })
db.col.find({ field: { $type: "objectid" } })
db.col.find({ field: { $type: "int" } })
db.col.find({ field: { $type: "bool" } })
db.col.find({ field: { $type: "objectId" } })
Edge Case 6: Null is Its Own BSON Type (type 10)
db.users.find({ middleName: { $type: "null" } })
db.users.find({ middleName: { $exists: true, $type: "null" } })
Edge Case 7: Using $exists: false in updateMany — Safe Pattern
db.users.updateMany(
{ emailVerified: { $exists: false } },
{ $set: { emailVerified: false } }
)
db.users.countDocuments({ emailVerified: { $exists: false } })
TIP
The $exists: false + $set pattern is the standard MongoDB approach for backfilling a new required field across an existing collection without touching documents that already have it set.