Querying Documents
1. Finding All Documents
| Method | Notes |
|---|---|
| find() | Returns cursor |
| find({}) | Equivalent, explicit empty filter |
| toArray() | Materialize results |
| countDocuments({}) | Accurate count |
| estimatedDocumentCount() | Fast metadata count |
2. Finding Single Document
| Method | Notes |
|---|---|
| findOne(filter) | First match or null |
| findOne(filter, options) | options: projection, sort, collation |
| find(...).next() | Same effect, manual cursor |
3. Querying with Equality Conditions
| Pattern | Matches |
|---|---|
{name: "Alice"} | Exact equality |
{name: {$eq: "Alice"}} | Same, explicit |
{tags: "admin"} | Array contains "admin" |
{addr: {city: "NYC"}} | Exact subdoc (field order!) |
{"addr.city": "NYC"} | Nested field equality |
4. Using Comparison Operators
| Operator | Meaning |
|---|---|
| $eq | Equal |
| $ne | Not equal |
| $gt / $gte | Greater (or equal) |
| $lt / $lte | Less (or equal) |
| $in / $nin | In / not in array |
db.products.find({ price: { $gte: 10, $lte: 50 }, stock: { $ne: 0 } });
5. Querying Arrays
| Pattern | Matches |
|---|---|
{tags: "x"} | Array contains "x" |
{tags: ["a","b"]} | Exact array equal |
{tags: {$all: ["a","b"]}} | Contains all listed |
{tags: {$size: 3}} | Array length = 3 |
{scores: {$elemMatch: {$gt: 80, $lt: 90}}} | Single element matches all conditions |
{"tags.0": "x"} | First element is "x" |
6. Querying Embedded Documents
| Pattern | Matches |
|---|---|
{"addr.city": "NYC"} | Nested field |
{items: {$elemMatch: {sku: "A", qty: {$gt: 0}}}} | Subdoc in array matches all |
{"items.sku": "A", "items.qty": {$gt: 0}} | Conditions may match different elements |
7. Using Logical Operators
| Operator | Form |
|---|---|
| $and | {$and: [c1, c2]} (implicit when fields differ) |
| $or | {$or: [c1, c2]} |
| $nor | Match none |
| $not | Negate a single operator expression |
db.users.find({ $or: [ {role: "admin"}, {role: "owner"} ], active: true });
8. Using $in and $nin Operators
| Operator | Behavior |
|---|---|
| $in: [v1, v2] | Field equals any value (or array contains any) |
| $nin: [v1, v2] | Field equals none (also matches missing fields) |
| Indexed? | Uses index; large $in can fan-out into seeks |
9. Checking Field Existence ($exists)
| Query | Matches |
|---|---|
{phone: {$exists: true}} | Field present (even null) |
{phone: {$exists: false}} | Field absent |
| Combined | {phone: {$exists: true, $ne: null}} |
10. Using Regular Expressions
| Form | Notes |
|---|---|
{name: /^Ali/} | JS regex literal |
{name: {$regex: "^Ali", $options: "i"}} | String form (for driver-agnostic) |
| Index use | Only anchored, case-sensitive prefixes use index efficiently |
11. Querying Null Values
| Query | Matches |
|---|---|
{x: null} | x is null OR field missing |
{x: {$type: "null"}} | Only explicit null |
{x: {$exists: true, $eq: null}} | Explicit null only |
{x: {$ne: null}} | Present and not null |
12. Using $expr for Expression Queries
| Use | Example |
|---|---|
| Compare 2 fields | {$expr: {$gt: ["$spent", "$budget"]}} |
| Arithmetic | {$expr: {$lt: [{$multiply: ["$qty","$price"]}, 1000]}} |
| Variables | Supports $$NOW, $$ROOT |
13. Using $type for Type Checking
| Alias | Code | Type |
|---|---|---|
| "double" | 1 | 64-bit float |
| "string" | 2 | UTF-8 string |
| "object" | 3 | Embedded doc |
| "array" | 4 | Array |
| "binData" | 5 | Binary |
| "objectId" | 7 | ObjectId |
| "bool" | 8 | Boolean |
| "date" | 9 | Date |
| "null" | 10 | Null |
| "int" | 16 | Int32 |
| "long" | 18 | Int64 |
| "decimal" | 19 | Decimal128 |
| "number" | - | Any numeric |