mongodb 7.5.0MongoDB Query Examples for Filters and Projection
Use practical MongoDB query examples for equality, comparison, arrays, nested fields, projection, sorting, limits, null values, and stable pagination.
Prepare a small dataset
Queries begin with a filter document. An empty filter matches every document, while field conditions narrow the result. Prepare a tagged dataset so each example is safe to rerun:
use("mongog_tutorial");
const books = db.collection("books");
books.deleteMany({ tutorial: "queries" });
books.insertMany([
{ title: "The Quiet Index", year: 2024, rating: 4.7, genres: ["technology", "fiction"], author: { country: "TR" }, inStock: true, tutorial: "queries" },
{ title: "Aggregation Harbor", year: 2026, rating: 4.9, genres: ["technology"], author: { country: "GB" }, inStock: true, tutorial: "queries" },
{ title: "Document Trails", year: 2022, rating: 4.2, genres: ["travel"], author: { country: "TR" }, inStock: false, tutorial: "queries" },
]);
Equality and comparison filters
Equality uses a direct field value. Comparison operators begin with $:
books.find({ tutorial: "queries", inStock: true });
books.find({
tutorial: "queries",
year: { $gte: 2024 },
rating: { $gt: 4.5 },
});
Conditions in the same filter are combined with logical AND. Use $or when any listed condition may match:
books.find({
tutorial: "queries",
$or: [
{ inStock: false },
{ rating: { $gte: 4.8 } },
],
});
Arrays and nested fields
A scalar condition on an array field matches documents where the array contains that value. Dot notation reaches an embedded field:
books.find({
tutorial: "queries",
genres: "technology",
"author.country": "TR",
});
Use $elemMatch when multiple conditions must be satisfied by the same embedded array element. Without it, separate elements may satisfy separate conditions.
Projection, sort, and limit
Projection controls which fields are returned. Include fields with 1; _id can be excluded explicitly. Chain cursor methods to order and bound the result:
books.find(
{ tutorial: "queries", rating: { $gte: 4.0 } },
{ projection: { _id: 0, title: 1, year: 1, rating: 1 } },
).sort({ rating: -1, title: 1 }).limit(2);
This sort uses rating descending, then title ascending to make ties deterministic. A stable secondary key matters when results are paged or repeatedly displayed.
Read one document
Use findOne() when at most one document is needed:
const book = books.findOne({ title: "Aggregation Harbor", tutorial: "queries" });
printjson(book);
MongoG resolves the operation before printjson() runs. When no document matches, the driver returns null.
Expected result
The projected query returns at most two documents, ordered by rating, and omits fields that the result view does not need. The original stored documents remain unchanged.
Distinguish missing fields from null
MongoDB’s { field: null } condition can match both an explicit null and a missing field. Use $exists when the distinction matters:
books.find({
tutorial: "queries",
subtitle: { $exists: false },
});
books.find({
tutorial: "queries",
subtitle: { $type: "null" },
});
Schema conventions should define whether absence and null communicate different domain states. Mixing both unintentionally makes filters and indexes harder to reason about.
Use range pagination for deep result sets
For a feed ordered by newest _id, remember the last value from the current page and request values below it:
const pageSize = 20;
const lastSeenId = ObjectId("66b0a2b8f20b2b4f0b17a001");
books.find({
tutorial: "queries",
_id: { $lt: lastSeenId },
}).sort({ _id: -1 }).limit(pageSize);
This uses the _id index as a range boundary. It does not provide a stable historical snapshot while other writers add or remove documents, but it avoids walking every skipped record. For a compound business sort, include all ordering fields and a unique tie-breaker in both the index and range condition.
Inspect query shape and collation
String comparison is binary by default. Case-insensitive or locale-aware rules require a collation on the operation and an index built with a compatible collation. Regular expressions that ignore case do not automatically behave like a well-designed indexed collation query.
Practice by adding optional subtitles and repeated ratings to the tutorial dataset. Query missing versus explicit-null values, create a deterministic rating/title/_id sort, and return two range-based pages without skip().
Common mistakes
- Writing
{ year: "$gte: 2024" }stores an ordinary string condition. Operators must be nested objects such as{ year: { $gte: 2024 } }. - Mixing inclusion and exclusion projection for ordinary fields is not allowed;
_idis the main exception. - Sorting a large unindexed result can consume memory and add latency. Use
explain()and an index for important access paths. - Using
skip()for very deep pages makes the server walk discarded records. Prefer range pagination with a stable indexed key. - Assuming
{ field: null }means only explicit null values can accidentally include documents where the field is absent. - Sorting by a non-unique field without a tie-breaker can make page boundaries unstable.
Continue learning
Learn how to find strings with regular expressions, query array fields, and build a correct date-range query. Then update and delete matching documents and use indexes with explain plans to evaluate important access paths. See the official find operations guide.