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

mongodump is a utility for creating a binary export of the contents of a database. mongodump can export data from either mongod or mongos instances; i.e. can export data from standalone, replica set, and sharded cluster deployments.

https://docs.mongodb.com/

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 by mongodump

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:

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.

https://docs.mongodb.com

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. --drop does not drop collections that are not in the backup.

https://docs.mongodb.com/

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 mergemongoimport 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.