Querying & Filtering
Element Operators
$exists and $type for documents whose shape is not uniform.
Flexible schema means some users have nickname, some do not, and age might be stored as a number on new documents and a string on old ones. $exists and $type query that mess instead of pretending every document looks like Rahul.
db.users.find({ nickname: { $exists: true } })
db.users.find({ nickname: { $exists: false } })
// missing OR explicit null
db.products.find({ discontinuedAt: null }){ nickname: { $exists: false } } — the key is not on the document. { nickname: null } — missing or set to null. Those are different. If you need 'key is there and is null', combine $exists: true with $eq: null.
db.users.find({ age: { $type: "string" } })
db.users.find({ age: { $type: ["int", "double", "long"] } })$type accepts a BSON alias ("int", "string", "date", "objectId", "array", "object", "bool", "null", "decimal") or the numeric code. An array of types is OR. This is how you find the documents that will miss { age: { $gt: 25 } } because age is "28".
Interview question
What is the difference between a missing field and a field set to null?
Missing: the key is not on the document. Null: the key is there and the value is null. { field: null } matches both. $exists: false matches only missing. $exists: true matches null and any other value.