0% completed
What is a MongoDB Query?
On This Page
Writing a Filter
Sorting and Limiting
Choosing Fields
How the Parts Work Together
Reading Large Results
Calculations on the Results
Key Takeaways
db.users.find({ age: { $gte: 30 } })
[ { _id: 2, name: 'Bob', age: 30, email: 'bob@example.com' }, { _id: 3, name: 'Charlie', age: 35, email: 'charlie@example.com' } ]
That line is a MongoDB query, a request to retrieve data from a collection. Its argument states which documents you want, and here $gte means "greater than or equal to", which is why the server returned the users aged 30 or older. The argument is called a query filter: a document that describes the condition each result must meet.
To run the query yourself, first create the three users. The drop() removes any earlier users collection, and only these three documents then exist.
db.users.drop() db.users.insertMany([ { _id: 1, name: "Alice", age: 25, email: "alice@example.com" }, { _id: 2, name: "Bob", age: 30, email: "bob@example.com" }, { _id: 3, name: "Charlie", age: 35, email: "charlie@example.com" } ])
Writing a Filter
The simplest filter names a field and a value, and it matches documents where the field equals that value. The comparison on strings is case sensitive, so the first query below returns Bob and the second returns nothing.
db.users.find({ name: "Bob" }) db.users.find({ name: "bob" })
An empty filter, or no filter at all, matches every document. A filter with several fields requires all of them to match. This query again returns only Bob, because Charlie is old enough but has a different name:
db.users.find({ age: { $gte: 30 }, name: "Bob" })
When no document matches, find() returns an empty result and does not raise an error. The related method findOne() returns the first matching document directly, not inside an array, and it returns null when nothing matches.
Sorting and Limiting
The filter decides which documents to return, but it says nothing about their order. Without a sort, MongoDB does not guarantee any order, even when the results appear to follow the order of insertion. To request one, add sort(), where 1 means ascending and -1 means descending.
db.users.find({ age: { $gte: 30 } }).sort({ age: -1 })
[ { _id: 3, name: 'Charlie', age: 35, email: 'charlie@example.com' }, { _id: 2, name: 'Bob', age: 30, email: 'bob@example.com' } ]
limit() sets the maximum number of results, and combining the two gives the oldest user who matches:
db.users.find({ age: { $gte: 30 } }).sort({ age: -1 }).limit(1)
[ { _id: 3, name: 'Charlie', age: 35, email: 'charlie@example.com' } ]
The order in which you write these two methods does not change the result. Writing .limit(1).sort({ age: -1 }) also returns Charlie, because the server always sorts before it limits.
Choosing Fields
So far each result has contained the whole document. A second argument to find(), called a projection, selects the fields to return. Set a field to 1 to include it. The _id field is included unless you set it to 0.
db.users.find({ age: { $gte: 30 } }, { name: 1, _id: 0 })
[ { name: 'Bob' }, { name: 'Charlie' } ]
You can also set a field to 0 to exclude it and return the rest. Other than for _id, you cannot do both in one projection, and { name: 1, email: 0 } fails with Cannot do exclusion on field email in inclusion projection.
Requesting only the fields you need is more than a matter of neat output. When documents are large, a projection reduces the data that the server sends over the network, and your application has less to process.
How the Parts Work Together
A single query can use all of these parts. This one returns the name of the oldest user aged 30 or older:
db.users.find({ age: { $gte: 30 } }, { name: 1, _id: 0 }).sort({ age: -1 }).limit(1)
[ { name: 'Charlie' } ]
The sort can use age even though the projection removes age from the output, because the result is the same as if the server applied the steps in the order shown here.
Reading Large Results
find() does not return all of its documents at once. It returns a cursor, which is an object that gives you results as you ask for them. In mongosh, a collection with 25 documents therefore prints the first 20 followed by a message:
Type "it" for more
Typing it prints the remaining 5. In a program, you loop over the cursor instead.
Calculations on the Results
find() returns documents, not calculations. If you only need the number of matching documents, use countDocuments(). For calculations across documents, such as an average, use aggregate().
db.users.countDocuments({ age: { $gte: 30 } }) db.users.aggregate([{ $group: { _id: null, averageAge: { $avg: "$age" } } }])
2 [ { _id: null, averageAge: 30 } ]
Key Takeaways
- A query filter is a document that describes which documents to return, and all of its conditions must match.
- Without
sort(), the order of results is not guaranteed. sort()always runs beforelimit(), whichever you write first.- A projection selects fields, and
_idis included unless you exclude it.
Reading Progress
0%
On This Page
Writing a Filter
Sorting and Limiting
Choosing Fields
How the Parts Work Together
Reading Large Results
Calculations on the Results
Key Takeaways