MongoDB Read & Query Document (CRUD) Tutorial
In this MongoDB tutorial we learn about the second CRUD operation, how to read and query documents.
We also cover implicit and explicit conditional operators, meta operators and expressions, projection, limitation and ordering.
- How to query data from a Collection
- How to test for equality
- How to test for non-equality
- How to test numerical data that's less than a value
- How to test numerical data that's greater than a value
- How to test for equality on multiple values
- How to test for non-equality on multiple values
- The conditional $and operator
- The conditional $or operator
- The conditional $nor operator
- The conditional $not operator
- How to select only specific pieces of data from a document (Projection)
- How to limit the amount of documents shown
- How to skip one or more documents
- How to order query results
How to query data from a Collection
We can query the database to find documents, and their data, by using the db.collection.find() method.
db.collection.find(document)
Let’s create a few documents with users and their information for the example.
db.users.insert([
{
"age": 33,
"name": "John",
"email": "john@example.com"
},
{
"age": 28,
"name": "Jane",
"email": "jane@example.com"
}
])
If we don’t pass an argument to the method, it will return all the documents in the collection.
db.users.find()
By default the data is unformatted.
{ "_id" : ObjectId("5faba722eaeb0de0612c56ac"), "age" : 33, "name" : "John", "email" : "john@example.com" }
{ "_id" : ObjectId("5faba722eaeb0de0612c56ad"), "age" : 28, "name" : "Jane", "email" : "jane@example.com" }
If we want to format the data to an easier-to-read form, we simply append the .pretty() method to the command.
db.users.find().pretty()
{
"_id" : ObjectId("5faba722eaeb0de0612c56ac"),
"age" : 33,
"name" : "John",
"email" : "john@example.com"
}
{
"_id" : ObjectId("5faba722eaeb0de0612c56ad"),
"age" : 28,
"name" : "Jane",
"email" : "jane@example.com"
}
How to test for equality
MongoDB allows us to find only documents that contain a specific value. We do this by testing for a number of things, like equality.
For example, find all the users with “name” that is “John”.
db.users.find({ "name" : "John" })
The command above reads: in the users collection, find everything that has "John" in the "name" key
{ "_id" : ObjectId("5faba722eaeb0de0612c56ac"), "age" : 33, "name" : "John", "email" : "john@example.com" }
The example above would be the same as the following query in an RDB.
where name = 'John'
How to test for non-equality
If we want to find documents that doesn’t contain a specific value, we can test for non-equality.
To do this we add the $ meta operator followed by the ne (not equals) keyword in our comparison.
db.collection.find({ "key" : {$ne : value} })
The meta expression and the test value is in its own scope and so must be wrapped in open and close curly braces.
As an example, let’s find all users that doesn’t have the name “John”.
db.users.find({ "name" : {$ne : "John"} })
The command above reads: in the users collection, find everything that does not have "John" in the "name" key
{ "_id" : ObjectId("5faba722eaeb0de0612c56ad"), "age" : 28, "name" : "Jane", "email" : "jane@example.com" }
The example above would be the same as the following query in an RDB.
where name != 'John'
How to test numerical data that's less than a value
MongoDB allows us to test if a number value in our document(s) is less than a number we specify.
To do this we add the $ meta operator followed by the lt (less than) keyword in our comparison.
db.collection.find({ "key" : {$lt : num} })
As an example, let’s consider that we only want to find users that are younger than 30.
db.users.find({ "age" : {$lt : 30} })
The command above reads: in the users collection, find everything that has a value less than 30 in the "age" key
{ "_id" : ObjectId("5faba722eaeb0de0612c56ad"), "age" : 28, "name" : "Jane", "email" : "john@example.com" }
The example above would be the same as the following query in an RDB.
where age < 30
If we want to include the upper number, we can test with a less than or equal to expression by changing the meta expression keyword to lte (less than or equal).
db.collection.find({ "key" : {$lte : num} })
Basically, this will include the number we write in the expression.
db.users.find({ "age" : {$lte : 28} })
The command above reads: in the users collection, find everything that has a value less than or equal to 28 in the "age" key
{ "_id" : ObjectId("5faba722eaeb0de0612c56ad"), "age" : 28, "name" : "Jane", "email" : "jane@example.com" }
The example above would be the same as the following query in an RDB.
where age <= 28
How to test numerical data that's greater than a value
We can also test if a number value in our document(s) is greater than a specified number.
To do this we add the $ meta operator followed by the gt (greater than) keyword in our comparison.
db.collection.find({ "key" : {$gt : num} })
As an example, let’s consider that we only want to find users that are older than 30.
db.users.find({ "age" : {$gt : 30} })
The command above reads: in the users collection, find everything that has a value more than 30 in the "age" key
{ "_id" : ObjectId("5faba722eaeb0de0612c56ac"), "age" : 33, "name" : "John", "email" : "john@example.com" }
The example above would be the same as the following query in an RDB.
where age > 30
If we want to include the lower number, we can test with a greater than or equal to expression by changing the meta expression keyword to gte (greater than or equal).
db.collection.find({ "key" : {$gte : num} })
Basically, this will include the number we write in the expression.
db.users.find({ "age" : {$gte : 28} })
The command above reads: in the users collection, find everything that has a value more than or equal to 28 in the "age" key
{ "_id" : ObjectId("5faba722eaeb0de0612c56ac"), "age" : 33, "name" : "John", "email" : "john@example.com" }
{ "_id" : ObjectId("5faba722eaeb0de0612c56ad"), "age" : 28, "name" : "Jane", "email" : "jane@example.com" }
Both users are 28 or older so we get both their documents as the result.
The example above would be the same as the following query in an RDB.
where age >= 28
How to test for equality on multiple values
We can test if a value in our documents is the same as a list of values that we specify.
To do this we add the $ meta operator followed by the in keyword in our comparison and specify an array with more than one value.
db.collection.find({ "key" : {$in : [value_1, value_2] } })
As an example, let’s consider that we want to find users with the names “John” and “Jack”.
db.users.find({ "name" : {$in : ["John", "Jack"]} })
The command above reads: in the users collection, find everything that has “John” or “Jack” in the “name” key
The or in this command is implicit, we can also use an explicit OR for the condition.
{ "_id" : ObjectId("5faba722eaeb0de0612c56ac"), "age" : 33, "name" : "John", "email" : "john@example.com" }
We don’t have a “Jack” user in the collection so it just returns “John”.
How to test for non-equality on multiple values
We can test if a value in our documents is not the same as a list of values that we specify.
To do this we add the $ meta operator followed by the nin (not in) keyword in our comparison and specify an array with more than one value.
db.collection.find({ "key" : {$nin : [value_1, value_2] } })
As an example, let’s consider that we want to find users that don’t have the names “John” and “Jack”.
db.users.find({ "name" : {$nin : ["John", "Jack"]} })
The command above reads: in the users collection, find everything that doesn’t have “John” or “Jack” in the “name” key
The or in this command is implicit, we can also use an explicit OR for the condition.
{ "_id" : ObjectId("5faba722eaeb0de0612c56ad"), "age" : 28, "name" : "Jane", "email" : "jane@example.com" }
The conditional $and operator
MongoDB allows us to check if multiple different conditions are true by using the explicit AND operator.
To do this we add the $ meta operator, followed by the and keyword in our comparison and specify an array with more than one key:value pair.
db.collection.find({ $and: [ {key_1:value_1}, { key_2:value_2} ] })
As an example, let’s consider that we want to find all the users called “John” who is 33 years old.
db.users.find({ $and: [ {"name":"John"}, { "age": 33 } ] })
The command above reads: in the users collection, find everything that has "John" in the "name" key AND a value of 33 in the "age" key
{ "_id" : ObjectId("5faba722eaeb0de0612c56ac"), "age" : 33, "name" : "John", "email" : "john@example.com" }
If we change the age in the query to anything else, we won’t get the “John” document as the result. Both key:value pairs must match the condition.
We can also combine the AND operator with other conditions like GT.
For this we simply add the $gt meta expression where we need it, like the “age” condition.
db.users.find({ $and: [ {"name":"John"}, { "age": {$gt:30} } ] })
Remember to wrap the meta expression in its own set of curly braces.
The conditional $or operator
MongoDB allows us to check if one of multiple different conditions are true by using the explicit OR operator.
To do this we add the $ meta operator, followed by the or keyword in our comparison and specify an array with more than one key:value pair.
db.collection.find({ $or: [ {key_1:value_1}, { key_2:value_2} ] })
As an example, let’s consider that we want to find all the users called either “John” or “Jack”.
db.users.find({ $or: [ {"name":"John"}, { "name":"Jack" } ] })
The command above reads: in the users collection, find everything that has either "John" OR "Jack" in the "name" key
{ "_id" : ObjectId("5faba722eaeb0de0612c56ac"), "age" : 33, "name" : "John", "email" : "john@example.com" }
Even though we don’t have a user called “Jack”, the query still succeeded.
As with the AND operator, we can combine the OR with other conditions like NE.
For this we simply add the $ne meta expression where we need it, like the “name” condition.
db.users.find({ $or: [ {"name": {$ne:"John"} }, { "name":"Jack" } ] })
Remember to wrap the meta expression in its own set of curly braces.
The command above reads: in the users collection, find everything that has either "Jack" OR not "John" in the "name" key
{ "_id" : ObjectId("5faba722eaeb0de0612c56ad"), "age" : 28, "name" : "Jane", "email" : "jane@example.com" }
The conditional $nor operator
MongoDB allows us to check if one of multiple different conditions are not true by using the explicit NOR operator.
To do this we add the $ meta operator, followed by the nor keyword in our comparison and specify an array with more than one key:value pair.
db.collection.find({ $nor: [ {key_1:value_1}, { key_2:value_2} ] })
As an example, let’s consider that we want to find all the users that are not called either “John” or “Jack”.
db.users.find({ $nor: [ {"name":"John"}, { "name":"Jack" } ] })
The command above reads: in the users collection, find everything that doesn't have either "John" OR "Jack" in the "name" key
{ "_id" : ObjectId("5faba722eaeb0de0612c56ad"), "age" : 28, "name" : "Jane", "email" : "jane@example.com" }
As with the AND and OR operators, we can combine the NOR with other conditions like LT and GT.
For this we simply add their meta expressions where we need it, like the “age” condition.
db.users.find({ $nor: [ {"age": {$lt:30} }, { "age": {$gt:40} } ] })
Remember to wrap the meta expression in its own set of curly braces.
The command above reads: in the users collection, find everything that doesn't have a value less than 30 or greater than 40 in the "age" key
{ "_id" : ObjectId("5faba722eaeb0de0612c56ac"), "age" : 33, "name" : "John", "email" : "john@example.com" }
We get the user “John” as a result because his “age” is between 30 and 40.
The conditional $not operator
MongoDB allows us to check if one of multiple different conditions are not true by using the explicit NOT operator.
To do this we add the $ meta operator, followed by the not keyword in our comparison and specify an array with more than one key:value pair.
db.collection.find({ $not: [ {key_1:value_1}, { key_2:value_2} ] })
As an example, let’s consider that we want to find all the users that are not called “John” and are not 33 years old.
db.users.find({ $not: [ {"name":"John"}, { "age":33 } ] })
The command above reads: in the users collection, find everything that doesn't have "John" in the "name key and doesn't have 33 in the "age" key
{ "_id" : ObjectId("5faba722eaeb0de0612c56ad"), "age" : 28, "name" : "Jane", "email" : "jane@example.com" }
As with the other operators, we can combine the NOT with other conditions like GT.
For this we simply add their meta expressions where we need it, like the “age” condition.
db.users.find({ $not: [ {"name":"John" }, { "age": {$gt:30} } ] })
Remember to wrap the meta expression in its own set of curly braces.
The command above reads: in the users collection, find everything that isn't named "John" and is not older than 30
{ "_id" : ObjectId("5faba722eaeb0de0612c56ad"), "age" : 28, "name" : "Jane", "email" : "jane@example.com" }
We get the user “Jane” as a result because she is not named “John” and is younger than 30.
How to select only specific pieces of data from a document (Projection)
Projection in MongoDB means we can select only the data we need from the document, instead of selecting everything.
For example, if a document has 3 keys and we only need 1, then we can select only 1 key and display it.
To do this, we need to set the key with a value of 1 (true) or 0 (false) as the second argument.
db.collection.find({}, {key_1 : 1, key_2 : 0})
Let’s say we only want to display the name of the user. We need to set the other keys to 0.
db.users.find({},
{
_id : 0,
"age" : 0,
"email" : 0
}
)
{ "name" : "John" }
{ "name" : "Jane" }
How to limit the amount of documents shown
To limit documents in MongoDB, we need to append the .limit() method to db.collection.find() .
This method only accepts one argument, which is the number of documents we want to limit the results to.
db.collection.find().limit(num)
Let’s say we want to limit the results to only one.
db.users.find().limit(1)
MongoDB will show only the first matching result.
{ "_id" : ObjectId("5fad015593eba2b50e266e17"), "age" : 33, "name" : "John", "email" : "john@example.com" }
The default value is 0, so it will not limit any documents unless a number is specified.
How to skip one or more documents
If we want to skip a certain amount of documents from the result, we can use the .skip() method.
This method also only accepts one argument, which is the number of documents we want to skip starting at the first result.
db.collection.find().skip(num)
For example, let’s say we want to skip the first result.
db.users.find().skip(1)
{ "_id" : ObjectId("5fad015593eba2b50e266e18"), "age" : 28, "name" : "Jane", "email" : "jane@example.com" }
Jane is our second user so the method successfully skipped 1 document.
The default value is 0, so it will not skip any documents unless a number is specified.
How to order query results
If we want to sort documents in ascending or descending order, we can use the .sort() method.
This method accepts one argument, which is a list of fields with their sorting order. We use 1 for ascending order and -1 for descending order.
db.collection.find().sort({ key : -1 })
For example, let’s say we want to sort our users by name in ascending order (alphabetically).
db.users.find().sort({ "name" : 1 })
{ "_id" : ObjectId("5fad015593eba2b50e266e18"), "age" : 28, "name" : "Jane", "email" : "jane@example.com" }
{ "_id" : ObjectId("5fad015593eba2b50e266e17"), "age" : 33, "name" : "John", "email" : "john@example.com" }
This time “Jane” is sorted to show before “John”.