Mongodump and Mongorestore vs Mongoexport and Mongoimport
May 29th 2020
If you have worked with MongoDB you may know that there are two different ways to export and import a Mongo database: mongodump/mongorestore and mongoexport/mongoimport. Here we will discuss how to use both methods and when one method might work better than the other.
mongodump
https://docs.mongodb.com/
mongodump
is a utility for creating a binary export of the contents of a database.mongodump
can export data from eithermongod
ormongos
instances; i.e. can export data from standalone, replica set, and sharded cluster deployments.
Mongodump is typically used for a backup strategy. Say for instance, you are scheduling backups of your database on a daily basis using a cron job method. Using mongodump you can later restore your database with the mongorestore utility. We can look at a few of the command line options for the mongodump utility and walk through examples of how to use it. You can connect to your mongo database using either: --uri
with a correct formatted uri string OR with the --user
, --db
and --password
flag options but you cannot use a combination of both. To export a database called mydb
from your localhost with mongoexport you can use:
mongodump --user=myuser --db=mydb --password=somepass --authenticationDatabase=admin
Or with a Mongo URI format:
mongodump --uri="mongodb://myuser:somepass@localhost:27107/mydb?ssl=false&authSource=admin
This is assuming that the authentication db (which stores your database user) is different than the database that you would like to dump. If it’s the same, then you would change the --authenticationDatabase
flag to the correct database or in URI format the authSource
querystring option to the correct database.
Either of these methods dumps the whole database into a dump
directory (named dump by default), in the current working directory you ran the command in. Inside you will have a subfolder with the name of the database. In our case, there would be a sub directory inside called mydb
so your new folder structure would look like: ./dump/mydb
. Inside the database specific folder we will have two files for each collection in our database. We will have a BSON file and a JSON file for each collection. As the name implies the <collection>.metadata.json
files will hold metadata information such as options
, indexes
and ns
(for the collection namespace) for each of the collection. While the BSON file <collection>.bson
will hold the documents (data) for each collection.
In mongodump we can change the behavior of the output. For instance, if you want to change the name of the dump
directory you can use the --out
flag to specify the name of the directory you want the database dumped to. For instance, if we want to call our dump directory databases
instead of dump
we could use:
mongodump --user=myuser --db=mydb --password=somepass --authenticationDatabase=admin --out=databases
By default mongodump dumps all of the collections into our output folder and within a folder that reflects the name of the database. If for instance, you only want to back up one collection you can specify the --collection
flag with the name of the collection you would like to dump. Let’s say we wanted to only dump our product
collection we could run:
mongodump --user=myuser --db=mydb --password=somepass --authenticationDatabase=admin --out=databases --collection=product
This will now create a folder structure such that:
.
|_databases
|_mydb
|_product.metadata.json
|_product.bson
We can run this command as many times as we’d like, specifying one collection at a time to dump to backup. Doing so will not overwrite the contents of the output folder and you can sequentially dump collections. For instance, let’s add the order
collection to our out dump folder:
mongodump --user=myuser --db=mydb --password=somepass --authenticationDatabase=admin --out=databases --collection=order
We should now see inside our databse/mydb
folder the order.metadata.json
and order.bson
added:
.
|_databases
|_mydb
|_product.metadata.json
|_product.bson
|_order.metadata.json
|_order.bson
We can also run the database backup to an archive file, instead of dumping all of the files into a dump directory. This is useful if you are transferring files between hosts or sending backup files between servers. The --archive
flag allows us to specify the name of the archive file. Note, you cannot use the --archive
flag and --out
flags together in the same mongodump command. The --archive
option creates one file for us which we can use to reimport the database with mongorestore
.
mongodump --db=mydb --username=myuser --password=somepass --authenticationDatabase=admin --archive=mydb.archive
Mongorestore
The compliment to mongodump is thee mongorestore utility to restore a mongo database
The
mongorestore
program loads data from either a binary database dump created bymongodump
One main difference between mongorestore and mongoimport is that mongorestore is insert only. This means that it will not overwrite a document in the database that already exists:
https://docs.mongodb.com
mongorestore
can create a new database or add data to an existing database. However,mongorestore
performs inserts only and does not perform updates. That is, if restoring documents to an existing database and collection and existing documents have the same value_id
field as the to-be-restored documents,mongorestore
will not overwrite those documents.
The only thing that is required to restore a database is the path to the dump directory such as:
mongorestore dump/
This would of course use the default localhost as the host and create database(s) with the names of the sub-folders contained within the dump
directory. If you are restoring to a remote host you will need to specify either a --uri
flag or all of the connection variables needed to connect: --host
, --db
, --username
, --port
, --password
.
Mongorestore allows you to do some partial restore options by specifying a collection, or list of collections, that you would like to restore to your database. If you are only needing to restore one collection you can use the --collection
flag in which you will need to specify the --db
flag with the database you are restoring to as well as a path to the collections BSON
file. The --collection
name will be the new name of the collection in the database:
mongorestore --db=mynewdb --collection=newcollection dump/mydb/product.bson
Using the --collection
flag can work, but the recommended way to restore collection(s) is to use the --nsInclude
option. The nsInclude option allows you to specify a namespace pattern in which to use to restore collections into a mongo database. Let’s say for instance that in your dump
directory you dumped two databases: production
and staging
so your folder structure would look like:
.
|_dump
|_production
|_product.metadata.json
|_product.bson
|_order.metadata.json
|_order.bson
|_staging
|_product.metadata.json
|_product.bson
|_order.metadata.json
|_order.bson
Let’s say you wanted to restore the staging
database into your local environment. The –nsInclude allows you to do this with namespace pattern matching:
mongorestore --db=mydb --nsInclude="staging.*" dump/
This will restore all of the collections from our staging database dump into our localhost database named mydb, but will not restore the production database in our dump directory. We can also change the name of our collection that we’re importing with the flags --nsFrom
and --nsTo
to change the name of our collection in our imported database. Let’s say that we want to change the collection product
from our dumped database to widget
. We can use the --nsFrom
and --nsTo
during import such that:
mongorestore --db=mydb --nsInclude="staging.*" --nsFrom="staging.product" --nsTo="mydb.widget" dump/
We can also use mongorestore to restore from an archive file that we created during mongoexport. To restore from an archive file, run mongorestore
with the new --archive
option and the archive filename.
mongorestore --archive=mydb.archive --nsInclude="mydb.*" --nsFrom="mydb.*" --nsTo="newdb.*"
If we are restoring to a database that already has collections with the same name as in our dump database/archive we can use the --drop
flag to drop the collections before they are restored.
Before restoring the collections from the dumped backup, drops the collections from the target database.
https://docs.mongodb.com/--drop
does not drop collections that are not in the backup.
Finally, if you want to test if a mongorestore
will work before importing the database you can use the --dryRun
to test if the restore will work as expected. With the --dryRun
flag mongorestore will return the mongorestore summary information without importing any data.
Mongoexport
The mongoexport utility is similar to mongodump but rather than creating a dump
directory with BSON
files, the mongoexport utility is used to produce JSON
output (or CSV) files from your mongo database. The mongoexport is typically used to export a collection from the mongo database and has more options and granularity on which fields within each document record to export.
For our example, we will have a mongo database called ecommerce
that has product
collection and order
collection in which we will want to use the mongoexport to export those collections and specify the fields that we will want contained within our JSON file.
By default, mongoexport prints the output to stdout but we can specify an output file by using the --out
flag. Also, since the default export function prints all of the documents in a collection outside of array format so they are all printed in the root element of the json file, which may not be expected if you are expecting documents in a JSON array. We can change the behavior by using the --jsonArray
flag. We can also add some formatting to our output file by using the --pretty
flag.
Let’s export the product collection in our ecommerce
mongo database to a file called product.json
mongoexport --db=ecommerce --username=myuser --password=somepass --collection=product --jsonArray --pretty --out="product.json"
After running this command we should have a file in our current directory called product.json
that would look similar to:
[
{
"_id":{
"$oid":"5d9788aedfe48c7bea5bf6b0"
},
"sale":0,
"price":1125,
"name":"Bent Bench",
"slug":"bent-bench",
"stock":100,
"attributes":[
{
"name":"size",
"options":[
{
"value":"Small",
"description":"76\" x 17\" x 18\""
},
{
"value":"Medium",
"description":"92\" x 15\" x 18\""
},
{
"value":"Large",
"description":"108\" x 15\" x 18\""
}
]
}
],
"description":"Crafted from solid acacia wood, the Bent Bench features true, live edges on heavy slabs of solid wood, and heavy-gauge, iron legs. Each piece is a solid work of art that will look great for years to come. The smoked-finish enhances the natural wood grain, giving the table a warm, caramel color. \n\n**Dimensions:** 92\"W x 15\"D x 18\"H \n\n**Materials:**\nSolid Acacia Wood\nIron Base",
"sku":"VE-1002-03",
"createdAt":{
"$date":"2019-10-04T18:00:14.745Z"
},
"updatedAt":{
"$date":"2020-03-27T21:30:03.421Z"
},
"__v":0,
"id":"5d9788aedfe48c7bea5bf6b0",
"published":true,
"featured":true
}
]
We are also able to create more granular output of our file by specifying the fields we want included in our output file. We can use the --fields
flag to specify which fields will be exported from our mongo documents in our product
collection. Let’s say for instance we only want the name
, slug
and description
of each product. We can run the mongoexport command that would look like:
mongoexport --db=ecommerce --username=myuser --password=somepass --collection=product --fields=name,slug,description --jsonArray --pretty --out="product.json"
And inside our output json file we would see the expected results which only include the name
, slug
and description
:
[
{
"_id":{
"$oid":"5d9788aedfe48c7bea5bf6b0"
},
"name":"Bent Bench",
"slug":"bent-bench",
"description":"Crafted from solid acacia wood, the Bent Bench features true, live edges on heavy slabs of solid wood, and heavy-gauge, iron legs. Each piece is a solid work of art that will look great for years to come. The smoked-finish enhances the natural wood grain, giving the table a warm, caramel color. \n\n**Dimensions:** 92\"W x 15\"D x 18\"H \n\n**Materials:**\nSolid Acacia Wood\nIron Base"
},
{
"_id":{
"$oid":"5d97871ddfe48c7bea5bf6ad"
},
"name":"Bent Dining Table",
"slug":"bent-dining-table",
"description":"The Bent Collection is rustic and natural with unfinished edges. Other pieces in the collection include a small dining table, bench, and coffee table. Note that Product depth may vary due to natural wood variation.\n\nDimensions: 118\"W x 36\"D x 29\"H\n\nLength: 22\" (from side leg (straight part) to end of table); Length between the two legs: 74\"; Length: 5 3/4 \" (from where the base connects to the table to the edge of the table). Top 2\""
},
{
"_id":{
"$oid":"5d99ff6da87f6320ff9573e2"
},
"name":"Vintage Bench",
"slug":"vintage-bench",
"description":"True to its name, the Vintage Bench has history. Made with FSC Certified solid pine, this bench brings rustic style to your dining space and can fit up to three people. Note the unique stain to each piece and the subtle hints of its past life.\n\n**Dimensions**: 51\"W x 15\"D x 18\"H\n\n**Materials:**\nFSC Certified Solid Pine Wood"
}
]
Some other useful options included with the mongoexport utility would be the --skip
, --sort
and --limit
options; which as their names implies allow you to skip a certain amount of documents (say for instance if you are paginating through mongo documents), limit allows you to limit the number of exported documents from a collection and sort allows you to order the documents based on the field. For example, if we want to skip the first ten results, sort the products by ascending price and limit only five results we could run the command:
mongoexport --db=ecommerce --username=myuser --password=somepass --collection=product --fields=name,slug,description,price --sort="{price: 1}" --skip=10 --limit=5 --jsonArray --pretty --sort --out="product.json"
The mongoexport utility is best used for managing and exporting collections and filtering, sorting and filtering documents based on document field values. It is also used to export the data from your mongo database to CSV (comma separated value) format which can be imported into a SQL or relational database management system. The compliment to mongoexport utility would be the mongoimport utility to import collections into a mongo database.
Mongoimport
The mongoimport
tool imports content from an extended JSON, CSV, or TSV export created by mongoexport
, or potentially, another third-party export tool.
The big difference between mongorestore and the mongoimport utility is the --mode
flag which has the options of: insert, upsert and merge. Let’s explore each:
Monogimport insert mode
Insert the documents in the import file. mongoimport will log an error if you attempt to import a document that contains a duplicate value for a field with a unique index, such as _id
. This mode expects that there are not documents in the collection.
Monogimport upsert mode
Replace existing documents in the database with matching documents from the import file. mongoimport will insert all other documents. By default mongoimport
matches documents based on the _id
field. The upsert mode replaces all document field data with the matching document in the import file. Consider the following:
We have a document in our product
collection in our ecommerce
database that looks like:
{
"_id":{
"$oid":"5d9788aedfe48c7bea5bf6b0"
},
"price":1125,
"name":"Bent Bench",
"slug":"bent-bench",
"description":"Crafted from solid acacia wood, the Bent Bench features true, live edges on heavy slabs of solid wood, and heavy-gauge, iron legs. Each piece is a solid work of art that will look great for years to come. The smoked-finish enhances the natural wood grain, giving the table a warm, caramel color. \n\n**Dimensions:** 92\"W x 15\"D x 18\"H \n\n**Materials:**\nSolid Acacia Wood\nIron Base"
}
If we have a document in our import JSON file with the same _id
value but different fields/field values than the document will be replaced.
{
"_id":{
"$oid":"5d9788aedfe48c7bea5bf6b0"
},
"price":999,
"name":"Bent Bench Replaced",
"slug":"bent-bench-replaced",
"description":"This is the replaced description for our bent bench.",
"excerpt": "This is a new field that did not exist before on the previous document that was in our collection."
}
Monogimport merge mode
Merge existing documents that match a document in the import file with the new document. mongoimport will insert all other documents. With --mode
merge
, mongoimport
enables you to merge fields from a new record with an existing document in the database.
This allows us to retain the field data in our current document, update the field data (if there is a field name in our current document that matches a field name in our imported documents) and add new fields to our current document (if the field names do not exist in our current document). Let’s say for example we are going to use the --mode=merge
in our previous example.
We have a document in our product
collection in our ecommerce
database that looks like:
{
"_id":{
"$oid":"5d9788aedfe48c7bea5bf6b0"
},
"price":1125,
"name":"Bent Bench",
"slug":"bent-bench",
"description":"Crafted from solid acacia wood, the Bent Bench features true, live edges on heavy slabs of solid wood, and heavy-gauge, iron legs. Each piece is a solid work of art that will look great for years to come. The smoked-finish enhances the natural wood grain, giving the table a warm, caramel color. \n\n**Dimensions:** 92\"W x 15\"D x 18\"H \n\n**Materials:**\nSolid Acacia Wood\nIron Base"
}
If we have a document in our import JSON file with the same _id
value but different fields/field values than the document such as:
{
"_id":{
"$oid":"5d9788aedfe48c7bea5bf6b0"
},
"description":"This is the replaced description for our bent bench.",
"excerpt": "This is a new field that did not exist before on the previous document that was in our collection."
}
During the import process, mongoimport
adds the new excerpt
field to the document and updates the description
field with the value from the imported document, but retains the price, name and slug fields as in the following:
{
"_id":{
"$oid":"5d9788aedfe48c7bea5bf6b0"
},
"price":1125,
"name":"Bent Bench",
"slug":"bent-bench",
"description":"This is the replaced description for our bent bench.",
"excerpt": "This is a new field that did not exist before on the previous document that was in our collection."
}
Summary
The mongodump/mongorestore utilities are perfect for a mongo database backup and restoration strategy. These utilities allow you to dump and restore from a single archive file that can easily be compressed and stored or transferred via email. The mongorestore allows you to include or exclude certain collections from being imported and/or restored into the new database with the --nsInclude
and --nsExclude
flag options. The mongoexport/mongoimport utilities are great for working with collections within a mongo database and inserting/updating documents within those collections. We can use the --mode
flag in mongoimport to define if we want to insert, replace or merge documents from our imported file. Next time you need a refresher on the mongo database utilities you can refer back to this in depth review of the dump, restore, export and import processes for mongodb.