MongoDB query operators decide which documents a read operation returns. They are the language of filters, search screens, dashboards, and API list endpoints.
This page is different from update operators: query operators select documents; update operators change matched documents.
A product catalog search may filter by category, price, rating, tags, and stock. Query operators express those conditions inside find() or $match without loading every document into application memory.
Use $gt, $gte, $lt, $lte, $eq, $ne, and $in to build ordinary filters. Add $or only when there are true alternatives, not as a replacement for clear field conditions.
Arrays need precise queries. $elemMatch is important when multiple conditions must apply to the same embedded element rather than any element in the array.
A correct query can still be slow. Use explain() to verify index usage and avoid filters that scan large collections unexpectedly.
Dot notation addresses a field inside an embedded document, such as "address.city". For an array of embedded documents, separate dotted predicates can match different elements; use $elemMatch when all conditions must hold for one element.
db.products.find({\n warehouses: {\n $elemMatch: { region: "west", stock: { $gte: 10 } }\n }\n})
Both region and stock must belong to the same array element.
A filter { field: null } can match an explicit null value or a missing field. Combine an appropriate type or existence condition when the distinction matters. MongoDB comparison behavior is type aware, so data that stores numbers as strings will not behave like a numeric range.
| Intent | Filter Shape |
|---|---|
| Field exists | { field: { $exists: true } } |
| Field is missing | { field: { $exists: false } } |
| Field has BSON null type | { field: { $type: 10 } } |
| Array has exact size | { tags: { $size: 3 } } |
| Every listed value is present | { tags: { $all: ["sale", "new"] } } |
Build filters from an allowlist of fields and operations. Never merge an arbitrary client object into a database query, because operator-bearing input can change the intended predicate. Parse numbers, dates, and identifiers at the API boundary before constructing the filter.
Use explain("executionStats") on representative data to inspect the winning plan, keys examined, documents examined, and returned rows. A compound index must reflect equality fields, sort order, and range fields used by the actual endpoint.
db.products.find({
category: { $in: ["keyboard", "mouse"] },
price: { $gte: 25, $lte: 150 },
rating: { $gte: 4 },
tags: { $elemMatch: { $eq: "wireless" } },
discontinued: { $ne: true }
})
They filter documents for read operations such as find(), countDocuments(), and aggregation $match.
No. Query operators select documents; update operators modify selected documents.
Explore 500+ free tutorials across 20+ languages and frameworks.