Learn Mongoose find() by Example
In Mongoose, the
Model.find()
function
is the primary tool for querying the database. The first parameter to
Model.find()
is a filter
object. MongoDB will search for all documents
that match the filter
. If you pass an empty filter,
MongoDB will return all documents.
In this tutorial, you'll see how to execute common queries in Mongoose by
structuring the filter
object using MongoDB query operators.
Equality Checks
Suppose you have a Character
model that contains 5 characters from
Star Trek: The Next Generation.
const Character = mongoose.model('Character', mongoose.Schema({
name: String,
age: Number,
rank: String
}));
await Character.create([
{ name: 'Jean-Luc Picard', age: 59, rank: 'Captain' },
{ name: 'William Riker', age: 29, rank: 'Commander' },
{ name: 'Deanna Troi', age: 28, rank: 'Lieutenant Commander' },
{ name: 'Geordi La Forge', age: 29, rank: 'Lieutenant' },
{ name: 'Worf', age: 24, rank: 'Lieutenant' }
]);
Suppose you want to find all characters whose rank
is 'Lieutenant'. The way
to do this is to pass { rank: 'Lieutenant' }
as the filter
.
const docs = await Character.find({ rank: 'Lieutenant' });
// MongoDB may return the docs in any order unless you explicitly sort
docs.map(doc => doc.name).sort(); // ['Geordi La Forge', 'Worf']
You can also query by age. For example, the below query will find all characters
whose age
is 29.
const docs = await Character.find({ age: 29 });
docs.map(doc => doc.name).sort(); // ['Geordi La Forge', 'William Riker']
The above examples don't use any query operators. If you set the value of rank
to an object with a $eq
property, you get an equivalent query, but using a query operator. The $eq
query operator
is usually not useful. But this example demonstrates the query operator syntax,
which you need for structuring non-trivial queries.
// Equivalent to `{ rank: 'Lieutenant' }`. `$eq` is an example of
// a "query operator"
const docs = await Character.find({ rank: { $eq: 'Lieutenant' } });
docs.map(doc => doc.name).sort(); // ['Geordi La Forge', 'Worf']
Comparisons
The $eq
query operator checks exact equality. There are also
comparison query operators like $gt
and $lt
. For example, suppose you want to find all characters whose age
is strictly less than 29. You can use the $lt
query operator as shown below.
const docs = await Character.find({ age: { $lt: 29 } });
docs.map(doc => doc.name).sort(); // ['Deanna Troi', 'Worf']
Suppose you wanted to find all characters whose age is at least 29. For that,
you should use the $gte
query operator.
const docs = await Character.find({ age: { $gte: 29 } });
// ['Geordi La Forge', 'Jean-Luc Picard', 'William Riker']
docs.map(doc => doc.name).sort();
The comparison operators $lt
, $gt
, $lte
, and $gte
work with more than just numbers. You can also use them on strings,
dates, and other types. MongoDB compares strings using unicode order.
If that order doesn't work for you, you can configure it using
MongoDB collations.
const docs = await Character.find({ name: { $lte: 'Geordi La Forge' } });
// ['Deanna Troi', 'Geordi La Forge']
docs.map(doc => doc.name).sort();
Regular Expressions
Suppose you want to find characters whose rank
contains 'Commander'. In SQL,
you would use the LIKE
operator.
In Mongoose, you can simply query by a regular expression as shown below.
const docs = await Character.find({ rank: /Commander/ });
// ['Deanna Troi', 'William Riker']
docs.map(doc => doc.name).sort();
Equivalently, you can use the $regex
query operator. This enables you to pass the regular expression as a string, which is convenient if you're getting the query from an HTTP request.
const docs = await Character.find({ rank: { $regex: 'Commander' } });
// ['Deanna Troi', 'William Riker']
docs.map(doc => doc.name).sort();
Composition with $and
and $or
If you set multiple filter
properties, MongoDB finds documents that match
all the filter properties. For example, the below query will find all characters
whose age
is at least 29 and whose rank
equals 'Commander'.
const docs = await Character.find({
age: { $gte: 29 },
rank: 'Commander'
});
// ['William Riker']
docs.map(doc => doc.name);
Suppose you want to find characters whose age
is at least 29 or whose
rank
equals 'Commander'. You would need the $or
query operator.
const docs = await Character.find({
$or: [
{ age: { $gte: 29 } },
{ rank: 'Commander' }
]
});
// ['Geordi La Forge', 'Jean-Luc Picard', 'William Riker']
docs.map(doc => doc.name).sort();
There is also a $and
query operator. You will rarely need to use the $and
query operator. The primary use case for $and
is to compose multiple $or
operators. For example, suppose you want
to find characters whose that satisfy both of the below conditions:
age
at least 29 or whoserank
equals 'Commander'name
starts with a letter before 'D' or after 'W'.
const docs = await Character.find({
$and: [
{
$or: [
{ age: { $gte: 29 } },
{ rank: 'Commander' }
]
},
{
$or: [
{ name: { $lte: 'D' } },
{ name: { $gte: 'W' } }
]
}
]
});
// ['William Riker']
docs.map(doc => doc.name).sort();