MongoDB from Basics to Production · MongoDB Basics

Query Operators, Projections and Sorting

Filter documents with comparison, logical, array and regex operators, return only needed fields, and sort and limit results.

Create a free account to save this page, take notes and track your progress. Sign in

What you'll build

Catalogue queries a shop needs: products in a price range, products with a tag, in-stock items from several categories, a case-insensitive name search, and a sorted, limited result with only the fields the page shows.

The idea

  • Comparison: $gt, $gte, $lt, $lte, $ne, $in, $nin. Logical: $and (implicit with several fields), $or, $not.
  • Arrays: matching a value matches any element; $all requires several; $elemMatch applies several conditions to the same element.
  • Projection ({ name: 1, price: 1, _id: 0 }) returns only listed fields.
  • sort, limit, skip shape results; sort on indexed fields for large collections.

The code

Filters, projections and sorting
db.products.insertMany([
  { _id: 1, name: "Mug", category: "kitchen", price: 8.5, stock: 40, tags: ["ceramic", "gift"] },
  { _id: 2, name: "Teapot", category: "kitchen", price: 24, stock: 5, tags: ["cast-iron"] },
  { _id: 3, name: "Kettle", category: "appliances", price: 31.9, stock: 0, tags: ["electric"] },
  { _id: 4, name: "Tea sampler", category: "food", price: 12, stock: 120, tags: ["gift", "organic"] },
]);

const show = (label, cursor) => print(label + ":", JSON.stringify(cursor.toArray()));

show("10 to 30", db.products.find({ price: { $gte: 10, $lte: 30 } }, { _id: 0, name: 1, price: 1 }));
show("gift tag", db.products.find({ tags: "gift" }, { _id: 0, name: 1 }));
show("in stock, kitchen or food", db.products.find(
  { stock: { $gt: 0 }, category: { $in: ["kitchen", "food"] } }, { _id: 0, name: 1 }));
show("name contains 'tea'", db.products.find({ name: { $regex: "tea", $options: "i" } }, { _id: 0, name: 1 }));
show("cheap OR out of stock", db.products.find({ $or: [{ price: { $lt: 10 } }, { stock: 0 }] }, { _id: 0, name: 1 }));
show("top 2 by price", db.products.find({}, { _id: 0, name: 1, price: 1 }).sort({ price: -1 }).limit(2));

Output

10 to 30: [{"name":"Teapot","price":24},{"name":"Tea sampler","price":12}]
gift tag: [{"name":"Mug"},{"name":"Tea sampler"}]
in stock, kitchen or food: [{"name":"Mug"},{"name":"Teapot"},{"name":"Tea sampler"}]
name contains 'tea': [{"name":"Teapot"},{"name":"Tea sampler"}]
cheap OR out of stock: [{"name":"Mug"},{"name":"Kettle"}]
top 2 by price: [{"name":"Kettle","price":31.9},{"name":"Teapot","price":24}]

Run this on your computer — see “Get Started” for setup.

Common mistakes

  • Unanchored, case-insensitive regex searches on large collections: they can't use indexes efficiently. Use an anchored prefix or Atlas Search / text indexes.
  • Fetching whole documents for list pages; project only the fields you render.
  • Deep pagination with skip, which still walks over skipped documents (see the pagination lesson).

Key points

  • Combine comparison, logical and array operators in one filter document.
  • Project only the fields you need.
  • Sort and limit on the server, ideally on indexed fields.

Further reading: Query and projection operators · Query arrays

Practice questions

How do you match documents whose array field contains a value?

Answer

Query the field with the value directly, e.g. { tags: 'gift' }; it matches if any element equals the value.

What does $elemMatch do that plain array conditions don't?

Answer

It requires a single array element to satisfy all conditions, instead of different elements satisfying each condition.

Why use projections?

Answer

They reduce the data sent over the network and memory used by returning only the fields the application needs.

Open in the app to mark lessons complete, take notes and track your progress.

Was this page helpful?