How records are stored
- Each record is called a Document, which is BSON formatted.
- Documents are grouped into a Collection.
- Collections are grouped into a Database.
List all DB
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
List all collections
> show collections
>
This is a fresh installation so there is no collection yet.
Create and read documents
use <db> command
For MongoDB, we can use the use <db>
command to specify which database to use. A database is created automatically the first time a record is inserted.
Tell MongoDB to use database people
.
> use logbook
insertOne() method
As the name implies, insertOne() method inserts one document into a collection.
A sample document:
{
name: "Bob",
age: 21,
gender: "male",
level: 51
}
Insert the document into a collection called friends
:
> db.friends.insertOne(
... {
... name: "Bob",
... age: 21,
... gender: "male",
... level: 51
... }
... )
{
"acknowledged" : true,
"insertedId" : ObjectId("60ad00d9503eb5d1927bfd84")
}
From the above example, you can see that mongo shell allows multiple lines of input, indicated by ...
at the start of a line. Input is completed once a matching closing quote is entered.
After successful insertion, a JSON formatted response can be seen. The ObjectId
is the unique ID of this document.
find() method
To list all the documents within a collection, we can use the db.collectionName.find()
command:
> db.friends.find()
{ "_id" : ObjectId("60ad00d9503eb5d1927bfd84"), "name" : "Bob", "age" : 21, "gender" : "male", "level" : 51 }
findOne() method
findOne() method has the same syntax as find() method, but it will only return one document. If there are multiple matching documents, only the first document by natural ordering is returned.
insertMany() method
The insertOne()
method allows inserting one document only. To insert multiple documents, we can use the insertMany()
method, which accepts an array of documents.
An example array of entries:
[
{
name: "Mary",
age: 22,
gender: "female",
level: 72
},
{
name: "Tom",
age: 15,
gender: "male",
level: 10
}
]
Output of mongo shell:
> db.friends.insertMany(
... [
... {
... name: "Mary",
... age: 22,
... gender: "female",
... level: 72
... },
... {
... name: "Tom",
... age: 15,
... gender: "male",
... level: 10
... }
... ]
... )
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("60ad04d054f83016e147129d"),
ObjectId("60ad04d054f83016e147129e")
]
}
Confirm that the documents are inserted:
> db.friends.find()
{ "_id" : ObjectId("60ad00d9503eb5d1927bfd84"), "name" : "Bob", "age" : 21, "gender" : "male", "level" : 51 }
{ "_id" : ObjectId("60ad04d054f83016e147129d"), "name" : "Mary", "age" : 22, "gender" : "female", "level" : 72 }
{ "_id" : ObjectId("60ad04d054f83016e147129e"), "name" : "Tom", "age" : 15, "gender" : "male", "level" : 10 }
count() method
Use count()
query to count the documents in a collection:
> db.friends.count()
3
Filtering documents
By specifying some conditions, called Query Filter Documents, we can filter documents with the find()
query.
Query Filter Documents are BSON formatted, just like a typical document.
For example, to find a document in friends collection with the name Tom, we can use this query filter document:
{
name: "Tom"
}
Output:
// Find a friend with the name "Tom".
> db.friends.find({name: "Tom"})
{ "_id" : ObjectId("60ad04d054f83016e147129e"), "name" : "Tom", "age" : 15, "gender" : "male", "level" : 10 }
Another example:
// Find all male friends.
> db.friends.find({ gender: "male" })
{ "_id" : ObjectId("60ad00d9503eb5d1927bfd84"), "name" : "Bob", "age" : 21, "gender" : "male", "level" : 51 }
{ "_id" : ObjectId("60ad04d054f83016e147129e"), "name" : "Tom", "age" : 15, "gender" : "male", "level" : 10 }
More than one conditions:
// Find friends that are both "male" and age 15.
> db.friends.find({ gender: "male", age: 15 })
{ "_id" : ObjectId("60ad04d054f83016e147129e"), "name" : "Tom", "age" : 15, "gender" : "male", "level" : 10 }
Field names and values are case sensitive. The following queries yield no results:
> db.friends.find({ name: "tom" })
> db.friends.find({ Name: "Tom" })
Query operators
Query operators allow me to use comparitive functions, such as $eq
for “equal”, $gt
for “greater than”, etc.
A list of all operators: https://docs.mongodb.com/manual/reference/operator/query/#comparison
Using the operators, we can filter documents with this syntax: { field: { operator: value }}
$gt (greater than)
Find friends that are more than 15 years old:
> db.friends.find({ age: { $gt: 15 }})
{ "_id" : ObjectId("60ad00d9503eb5d1927bfd84"), "name" : "Bob", "age" : 21, "gender" : "male", "level" : 51 }
{ "_id" : ObjectId("60ad04d054f83016e147129d"), "name" : "Mary", "age" : 22, "gender" : "female", "level" : 72 }
$eq (equal)
Find all male friends that are more than 10 years old:
> db.friends.find({ age: { $gt: 10 }, gender: { $eq: "male" }})
{ "_id" : ObjectId("60ad00d9503eb5d1927bfd84"), "name" : "Bob", "age" : 21, "gender" : "male", "level" : 51 }
{ "_id" : ObjectId("60ad04d054f83016e147129e"), "name" : "Tom", "age" : 15, "gender" : "male", "level" : 10 }
$ne (not equal)
Find all friends that are not male:
> db.friends.find({ gender: { $ne: "male" }})
{ "_id" : ObjectId("60ad04d054f83016e147129d"), "name" : "Mary", "age" : 22, "gender" : "female", "level" : 72 }
$nin (not in)
Find all friends whose name is not in “Mary”, “Bob”, or “Superman”:
> db.friends.find({ name: { $nin: ["Mary", "Bob", "Superman"] }})
{ "_id" : ObjectId("60ad04d054f83016e147129e"), "name" : "Tom", "age" : 15, "gender" : "male", "level" : 10 }
Updating documents
There are 3 main shell methods that can update documents: updateOne()
, updateMany()
and replaceOne()
.
Assuming in database people, collection friends, there are these documents:
{ "_id" : ObjectId("60ad00d9503eb5d1927bfd84"), "name" : "Bob", "age" : 21, "gender" : "male", "level" : 51 }
{ "_id" : ObjectId("60ad04d054f83016e147129d"), "name" : "Mary", "age" : 22, "gender" : "female", "level" : 72 }
{ "_id" : ObjectId("60ad04d054f83016e147129e"), "name" : "Tom", "age" : 15, "gender" : "male", "level" : 10 }
updateOne() method
updateOne() method is used on a collection. It has the following syntax:
db.collection.updateOne( <filter>, <update>, <options>)
.
Where <filter> is a Query Filter Document, as described in the chapter above;
<update> is a document containing a set of update operators and values;
<options> is optional and is used to specify some features that are out of the scope of this level.
Example syntax:
db.inventory.updateOne(
{ item: "paper" },
{
$set: { "size.uom": "cm", status: "P" },
$currentDate: { lastModified: true }
}
)
In the above example, the update operator, $set
, is used to specify <field>:<value> pairs to be updated. $currentDate
operator is used to update a field (lastModified) with the current timestamp.
Bob’s record before being updated:
> db.friends.find({ name: "Bob" })
{ "_id" : ObjectId("60ad00d9503eb5d1927bfd84"), "name" : "Bob", "age" : 21, "gender" : "male", "level" : 51 }
We can update Bob’s record like this:
// For a document with the name "Bob", set the field "age" to 35.
> db.friends.updateOne({ name: "Bob"}, {
... $set: {
... age: 35
... }
... })
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
Confirm that the value has been updated:
// Bob's age should be 35 now.
> db.friends.find({ name: "Bob" })
{ "_id" : ObjectId("60ad00d9503eb5d1927bfd84"), "name" : "Bob", "age" : 35, "gender" : "male", "level" : 51 }
If a new field is specified in the $set
operator, the new field is inserted into the document:
> db.friends.updateOne({ name: "Bob"}, {
... $set: {
... nickname: "Bobby"
... }
... })
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
// Confirm that a new field named *nickname* is inserted with the value *Bobby*.
> db.friends.find({ name: "Bob" })
{ "_id" : ObjectId("60ad00d9503eb5d1927bfd84"), "name" : "Bob", "age" : 35, "gender" : "male", "level" : 51, "nickname" : "Bobby" }
If a filter matches more than one document, only the first one sorted by _id is updated:
> db.friends.updateOne({ gender: "male" }, {
... $set: {
... level: 47
... }
... })
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
// Check records. Only Bob with the lower _id is updated.
> db.friends.find()
{ "_id" : ObjectId("60ad00d9503eb5d1927bfd84"), "name" : "Bob", "age" : 35, "gender" : "male", "level" : 47, "nickname" : "Bobby" }
{ "_id" : ObjectId("60ad04d054f83016e147129d"), "name" : "Mary", "age" : 22, "gender" : "female", "level" : 72 }
{ "_id" : ObjectId("60ad04d054f83016e147129e"), "name" : "Tom", "age" : 15, "gender" : "male", "level" : 10 }
updateMany() method
updateMany() accepts the same parameters as updateOne(), but it will update all records that matched the filter.
Set the level of all male friends to 99:
> db.friends.updateMany({ gender: "male" }, {
... $set: {
... level: 99
... }
... })
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }
// Check records. All male friends are now level 99.
> db.friends.find()
{ "_id" : ObjectId("60ad00d9503eb5d1927bfd84"), "name" : "Bob", "age" : 35, "gender" : "male", "level" : 99, "nickname" : "Bobby" }
{ "_id" : ObjectId("60ad04d054f83016e147129d"), "name" : "Mary", "age" : 22, "gender" : "female", "level" : 72 }
{ "_id" : ObjectId("60ad04d054f83016e147129e"), "name" : "Tom", "age" : 15, "gender" : "male", "level" : 99 }
replaceOne() method
replaceOne() method finds the first matching document and replace all contents of the document.
It shares a similar syntax as the other two methods, but instead of accepting update operators, it only accepts a replacement document.
Example syntax:
db.collection.replaceOne(
<filter>,
<replacement>,
<options>
)
<options>
is optional, and it is out of the scope of this level.
Replace Tom with Batman:
> db.friends.replaceOne({ name: "Tom" }, {
... name: "Batman",
... gender: "male",
... level: 512,
... type: "superhero"
... })
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
// Check records. Tom has been replaced with Batman. Note that the _id is not changed.
> db.friends.find()
{ "_id" : ObjectId("60ad00d9503eb5d1927bfd84"), "name" : "Bob", "age" : 35, "gender" : "male", "level" : 99, "nickname" : "Bobby" }
{ "_id" : ObjectId("60ad04d054f83016e147129d"), "name" : "Mary", "age" : 22, "gender" : "female", "level" : 72 }
{ "_id" : ObjectId("60ad04d054f83016e147129e"), "name" : "Batman", "gender" : "male", "level" : 512, "type" : "superhero" }
Delete documents
There are two methods to delete documents: deleteOne()
and deleteMany()
.
As the name suggests, deleteOne()
deletes the first document that matches a given filter, while deleteMany()
deletes all documents that match a given filter. They both accept optional options that are not within the scope of this level.
Insert some more sample documents:
db.friends.insertMany([
{
name: "Catwoman",
type: "superhero",
level: 202
},
{
name: "Superman",
type: "superhero",
level: 792
},
{
name: "Wonderwoman",
type: "superhero",
level: 666
},
{
name: "One Punch Man",
type: "superhero",
level: 999
},
{
name: "Thanos",
type: "villain",
level: -1
},
{
name: "Joker",
type: "villain",
level: 444,
}
])
Output:
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("60ae4c21e93e0f580cacbcd0"),
ObjectId("60ae4c21e93e0f580cacbcd1"),
ObjectId("60ae4c21e93e0f580cacbcd2"),
ObjectId("60ae4c21e93e0f580cacbcd3"),
ObjectId("60ae4c21e93e0f580cacbcd4"),
ObjectId("60ae4c21e93e0f580cacbcd5")
]
}
deleteOne() method
Remove Joker from the collection:
> db.friends.deleteOne({ name: "Joker" })
{ "acknowledged" : true, "deletedCount" : 1 }
// Confirm that Joker has been deleted.
> db.friends.find()
{ "_id" : ObjectId("60ad00d9503eb5d1927bfd84"), "name" : "Bob", "age" : 35, "gender" : "male", "level" : 99, "nickname" : "Bobby" }
{ "_id" : ObjectId("60ad04d054f83016e147129d"), "name" : "Mary", "age" : 22, "gender" : "female", "level" : 72 }
{ "_id" : ObjectId("60ad04d054f83016e147129e"), "name" : "Batman", "level" : 512, "type" : "superhero" }
{ "_id" : ObjectId("60ae4c21e93e0f580cacbcd0"), "name" : "Catwoman", "type" : "superhero", "level" : 202 }
{ "_id" : ObjectId("60ae4c21e93e0f580cacbcd1"), "name" : "Superman", "type" : "superhero", "level" : 792 }
{ "_id" : ObjectId("60ae4c21e93e0f580cacbcd2"), "name" : "Wonderwoman", "type" : "superhero", "level" : 666 }
{ "_id" : ObjectId("60ae4c21e93e0f580cacbcd3"), "name" : "One Punch Man", "type" : "superhero", "level" : 999 }
{ "_id" : ObjectId("60ae4c21e93e0f580cacbcd4"), "name" : "Thanos", "type" : "villain", "level" : -1 }
deleteMany() method
Remove all friends that do not have the field named type, or the type is not in superhero or villain:
> db.friends.deleteMany({
... type: { $exists: false, $nin: ["superhero", "villain" ] }
... })
{ "acknowledged" : true, "deletedCount" : 2 }
// Check records.
> db.friends.find()
{ "_id" : ObjectId("60ad04d054f83016e147129e"), "name" : "Batman", "level" : 512, "type" : "superhero" }
{ "_id" : ObjectId("60ae4c21e93e0f580cacbcd0"), "name" : "Catwoman", "type" : "superhero", "level" : 202 }
{ "_id" : ObjectId("60ae4c21e93e0f580cacbcd1"), "name" : "Superman", "type" : "superhero", "level" : 792 }
{ "_id" : ObjectId("60ae4c21e93e0f580cacbcd2"), "name" : "Wonderwoman", "type" : "superhero", "level" : 666 }
{ "_id" : ObjectId("60ae4c21e93e0f580cacbcd3"), "name" : "One Punch Man", "type" : "superhero", "level" : 999 }
{ "_id" : ObjectId("60ae4c21e93e0f580cacbcd4"), "name" : "Thanos", "type" : "villain", "level" : -1 }
Remove all documents with level greater than 600 AND less than 900, using the $and
query operator:
> db.friends.deleteMany({
... $and: [
... { level: { $gt: 600} },
... { level: { $lt: 900} }
... ]
... })
{ "acknowledged" : true, "deletedCount" : 2 }
// Confirm deleted documents
> db.friends.find()
{ "_id" : ObjectId("60ad04d054f83016e147129e"), "name" : "Batman", "level" : 512, "type" : "superhero" }
{ "_id" : ObjectId("60ae4c21e93e0f580cacbcd0"), "name" : "Catwoman", "type" : "superhero", "level" : 202 }
{ "_id" : ObjectId("60ae4c21e93e0f580cacbcd3"), "name" : "One Punch Man", "type" : "superhero", "level" : 999 }
{ "_id" : ObjectId("60ae4c21e93e0f580cacbcd4"), "name" : "Thanos", "type" : "villain", "level" : -1 }
We can also write the above query without the $and
operator since combined operators for a field is treated as an implicit AND operation:
db.friends.deleteMany({
level: {
$gt: 600,
$lt: 900
}
})
Remove all documents in a collection
By specifying an empty filter document with the deleteMany()
method, all documents in a collection will be deleted:
> db.friends.deleteMany({})
{ "acknowledged" : true, "deletedCount" : 4 }
> db.friends.find()
// No output, meaning no document exists in the collection.
All 4 remaining documents in friends collection are deleted.
Drop a collection
drop() method
This method drops a collection from a database. It can run without any parameters, but can optionally accept options that are outside of the scope of this level.
Remove collection friends from database people:
> use people
switched to db people
> show collections
friends
> db.friends.drop()
true
> show collections
// No output.