Use Liquibase with MongoDB

MongoDB is a document-oriented NoSQL database. For more information, see MongoDB Documentation.

Supported versions

Note: Liquibase does not support the version of MongoDB used with AWS DocumentDB or Azure Cosmos DB .

Prerequisites

  1. Introduction to Liquibase – Dive into Liquibase concepts.
  2. Install Liquibase – Download Liquibase on your machine.
  3. Get Started with Liquibase – Learn how to use Liquibase with an example database.
  4. init project – Create a new Liquibase project folder to store all Liquibase files.
  5. How to Apply Your Liquibase Pro License Key – If you use Liquibase Pro, activate your license.

6. Ensure that your MongoDB Pro Extension User Roles are established before continuing.

Install drivers

To use Liquibase and MongoDB, you need four JAR files:

Place your JAR file(s) in the liquibase/lib directory.

If you use Maven, you must include the driver JAR as a dependency in your pom.xml file.

To include the driver JAR in the pom.xml file, use the following code:

<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongodb-driver-core</artifactId>
    <version>4.9.0</version>
</dependency>
<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongodb-driver-sync</artifactId>
    <version>4.9.0</version>
</dependency>
<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>bson</artifactId>
    <version>4.9.0</version>
</dependency>
<dependency>
    <groupId>org.liquibase.ext</groupId>
    <artifactId>liquibase-mongodb</artifactId>
    <version>4.20.0</version>
</dependency>

Test your connection

  1. Ensure your MongoDB database is configured. See Install MongoDB for more information.
  2. Specify the database URL in the liquibase.properties file (defaults file), along with other properties you want to set a default value for. Liquibase does not parse the URL. You can either specify the full database connection string or specify the URL using your database's standard JDBC format:
  3. url: mongodb://hostname:27017/myDatabase
    

    Note: If you are unsure about how to configure the url property, refer to Connection String URI Format.

    Tip: To apply a Liquibase Pro key to your project, add the following property to the Liquibase properties file: licenseKey: <paste code here>

  4. Create a text file called changelog (.xml) in your project directory and add a changeset.

    Note: The use of JSON and YAML changelogs is available in Liquibase version 4.20

  5. XML example 1
    <?xml version="1.0" encoding="UTF-8"?>

    <databaseChangeLog
            xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:pro="http://www.liquibase.org/xml/ns/pro"
            xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.6.xsd
        http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-4.6.xsd ">

          <changeSet id="1" author="your.name" labels="example-label" context="example-context">
              <comment>example-comment</comment>
            <createTable tableName="person">
                <column name="id" type="int" autoIncrement="true">
                    <constraints primaryKey="true" nullable="false"/>
                </column>
                <column name="name" type="varchar(50)">
                    <constraints nullable="false"/>
                </column>
                <column name="address1" type="varchar(50)"/>
                <column name="address2" type="varchar(50)"/>
                <column name="city" type="varchar(30)"/>
            </createTable>
        </changeSet>

        <changeSet id="2" author="your.name" labels="example-label" context="example-context">
            <comment>example-comment</comment>
            <createTable tableName="company">
                <column name="id" type="int" autoIncrement="true">
                    <constraints primaryKey="true" nullable="false"/>
                </column>
                <column name="name" type="varchar(50)">
                    <constraints nullable="false"/>
                </column>
                <column name="address1" type="varchar(50)"/>
                <column name="address2" type="varchar(50)"/>
                <column name="city" type="varchar(30)"/>
            </createTable>
        </changeSet>

        <changeSet id="3" author="other.dev" labels="example-label" context="example-context">
            <comment>example-comment</comment>
            <addColumn tableName="person">
                <column name="country" type="varchar(2)"/>
            </addColumn>
        </changeSet>
    </databaseChangeLog>
    XML example 2
    <?xml version="1.0" encoding="UTF-8"?>

    <databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:mongodb-pro="http://www.liquibase.org/xml/ns/pro-mongodb"
    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd
    http://www.liquibase.org/xml/ns/pro-mongodb http://www.liquibase.org/xml/ns/pro-mongodb/liquibase-pro-mongodb-latest.xsd">
        <changeSet id="1" author="nvoxland" runWith="mongosh">
            <mongodb-pro:mongo>
    db = db.getSiblingDB( 'mydb' );
    db.createCollection('person2');
    </mongodb-pro:mongo>
            <rollback>
                <mongodb-pro:mongo>
    db = db.getSiblingDB( 'mydb' );
    db.person2.drop();
    </mongodb-pro:mongo>
            </rollback>
        </changeSet>
        <changeSet id="2" author="nvoxland" runWith="mongosh">
            <mongodb-pro:mongoFile path="scriptFile.js" relativeToChangelogFile="true"/>
            <rollback>
                <mongodb-pro:mongoFile path="scriptFile-rollback.js" relativeToChangelogFile="true"/>
            </rollback>
        </changeSet>
        <changeSet id="3" author="nvoxland" runWith="mongosh">
            <mongodb-pro:mongo>
    db.products.insertMany( [
    { item: "card", qty: 15 },
    { item: "envelope", qty: 20 },
    { item: "stamps" , qty: 30 }
    ] );
    </mongodb-pro:mongo>
            <rollback>
                <mongodb-pro:mongo>
    db.products.deleteMany( { } );
    </mongodb-pro:mongo>
            </rollback>
        </changeSet>
    </databaseChangeLog>
    YAML example
    databaseChangeLog:
    - changeSet:
          id:  1
          author:  your.name
          labels: example-label
          context: example-context
          comment: example-comment
          changes:
           - createTable:
                tableName:  person
                columns:
                  - column:
                      name:  id
                      type:  int
                      autoIncrement:  true
                      constraints:
                        primaryKey:  true
                        nullable:  false
                  - column:
                      name:  name
                      type:  varchar(50)
                      constraints:
                        nullable:  false
                  - column:
                      name:  address1
                      type:  varchar(50)
                  - column:
                      name:  address2
                      type:  varchar(50)
                  - column:
                      name:  city
                      type:  varchar(30)

    - changeSet:
          id:  2
          author:  your.name
          labels: example-label
          context: example-context
          comment: example-comment
          changes:
           - createTable:
                tableName:  company
                columns:
                  - column:
                      name:  id
                      type:  int
                      autoIncrement:  true
                      constraints:
                        primaryKey:  true
                        nullable:  false
                  - column:
                      name:  name
                      type:  varchar(50)
                      constraints:
                        nullable:  false
                  - column:
                      name:  address1
                      type:  varchar(50)
                  - column:
                      name:  address2
                      type:  varchar(50)
                  - column:
                      name:  city
                      type:  varchar(30)

    - changeSet:
          id:  3
          author:  other.dev
          labels: example-label
          context: example-context
          comment: example-comment
          changes:
           - addColumn:
                tableName:  person
                columns:
                  - column:
                      name:  country
                      type:  varchar(2
    JSON example
    JSON example
                            {
                            "databaseChangeLog": [
                            ---------------------------CREATE AND DROP COLLECTION---------------------------
                            {
                            "changeSet": {
                            "id": "1",
                            "author": "as",
                            "labels": "test_label",
                            "context": "test_context",
                            "comment": "test_comment",
                            "changes": [
                            {
                            "createCollection": {
                            "collectionName": "countries_json"
                            }
                            }
                            ]
                            }
                            },
                            {
                            "changeSet": {
                            "id": "2",
                            "author": "as",
                            "changes": [
                            {
                            "dropCollection": {
                            "collectionName": "towns_json"
                            }
                            }
                            ],
                            "rollback": ""
                            }
                            },
                            ---------------------------INSERT ONE---------------------------        
                            {
                            "changeSet": {
                            "id": "3",
                            "author": "as",
                            "changes": [
                            {
                            "insertOne": {
                            "collectionName": "towns_json",
                            "document": {
                            "$rawJson": {
                            "name": "New York",
                            "population": 222000000,
                            "famousFor": [ "the MOMA", "food", "Derek Jeter" ],
                            "mayor": {
                            "name": "Bill de Blasio",
                            "party": "D"
                            }
                            }
                            }
                            }
                            }
                            ],
                            "rollback": ""
                            }
                            },    
                            ---------------------------INSERT MANY---------------------------    
                            {
                            "changeSet": {
                            "id": "4",
                            "author": "as",
                            "changes": [
                            {
                            "insertMany": {
                            "collectionName": "countries_json",
                            "documents": {
                            "$rawJson": [
                            {
                            "_id" : "us",
                            "name" : "United States",
                            "exports" : {
                            "foods" : [
                            {"name" : "bacon", "tasty" : "true" },
                            {"name" : "burger"}
                            ]
                            }
                            },
                            {
                            "_id" : "ca",
                            "name" : "Canada",
                            "exports" : {
                            "foods" : [
                            {"name" : "bacon", "tasty" : false },
                            {"name" : "syrup", "tasty" : true}
                            ]
                            }
                            },
                            {
                            "_id" : "mx",
                            "name" : "Mexico",
                            "exports" : {
                            "foods" : [
                            {"name" : "salsa", "tasty" : true, "condiment" : true}
                            ]
                            }
                            }
                            ]
                            }
                            }
                            }
                            ],
                            "rollback": {
                            "runCommand": {
                            "command": "{ delete: \"countries_json\", deletes: [{q: { }, limit: 0}] }"
                            }
                            }
                            }
                            },
                            ---------------------------CREATE AND DROP INDEX---------------------------        
                            {
                            "changeSet": {
                            "id": "5",
                            "author": "as",
                            "changes": [
                            {
                            "createIndex": {
                            "collectionName": "countries_json",
                            "keys": {
                            "$rawJson": {
                            "name": 1,
                            "type": 1
                            }
                            },
                            "options": {
                            "$rawJson": {
                            "unique": true,
                            "name": "ui_countries_json"
                            }
                            }
                            }
                            }
                            ]
                            }
                            },
                            {
                            "changeSet": {
                            "id": "6",
                            "author": "as",
                            "changes": [
                            {
                            "dropIndex": {
                            "collectionName": "countries_json",
                            "keys": {
                            "$rawJson": {
                            "name": 1,
                            "type": 1
                            }
                            },
                            "options": {
                            "$rawJson": {
                            "unique": true,
                            "name": "ui_countries_json"
                            }
                            }
                            }
                            }
                            ]
                            }
                            },
                            ---------------------------RUN COMMAND---------------------------        
                            {
                            "changeSet": {
                            "id": "7",
                            "author": "as",
                            "changes": [
                            {
                            "runCommand": {
                            "command": "{ buildInfo: 1 }"
                            }
                            }
                            ],
                            "rollback": ""
                            }
                            },
                            ---------------------------ADMIN COMMAND---------------------------            
                            {
                            "changeSet": {
                            "id": "8",
                            "author": "as",
                            "changes": [
                            {
                            "adminCommand": {
                            "command": "{ buildInfo: 1 }"
                            }
                            }
                            ],
                            "rollback": ""
                            }
                            }
                            ]
                        }
  6. Navigate to your project folder in the CLI and run the Liquibase status command to see whether the connection is successful:
  7. liquibase status --username=test --password=test --changelog-file=<changelog.xml>
    

    Note: You can pass arguments in the CLI or keep them in the Liquibase properties file.

  8. Make changes to your database with the update command.
  9. liquibase update --changelog-file=<changelog.xml>
    
  10. From a database UI tool, ensure that your database contains myCollection along with the DATABASECHANGELOG table and DATABASECHANGELOGLOCK table.
  11. Tip: You can use MongoDB Compass to easily view collections in your database. For example, run the commands use myDatabase and db.myCollection.find().

MongoDB command examples

<changeSet id="1" author="liquibase">
    <ext:createCollection collectionName="myCollection">
        <ext:options>
        {
        validator: {
            $jsonSchema: {
                bsonType: "object",
                required: ["name", "address"],
                properties: {
                    name: {
                        bsonType: "string",
                        description: "The Name"
                    },
                    address: {
                       bsonType: "string",
                       description: "The Address"
                    }
                 }
              }
          },
          validationAction: "warn",
          validationLevel: "strict"
        }
        </ext:options>
    </ext:createCollection>
</changeSet>
<changeSet id="1" author="liquibase">
<ext:dropCollection collectionName="myCollection"/>
</changeSet>
<changeSet id="1" author="liquibase">
     <ext:createIndex collectionName="createIndexTest">
          <ext:keys>
               { clientId: 1, type: 1}
          </ext:keys>
          <ext:options>
               {unique: true, name: "ui_tppClientId"}
          </ext:options>
     </ext:createIndex>

     <ext:createIndex collectionName="createIndexNoOptionsTest">
          <ext:keys>
               { clientId: 1, type: 1}
          </ext:keys>
    </ext:createIndex>
</changeSet>
  • dropIndex drops an index for a collection by keys.
<changeSet id="1" author="liquibase">
     <ext:dropIndex collectionName="createIndexTest">
         <ext:keys>
             { clientId: 1, type: 1}
         </ext:keys>
         <ext:options>
             {unique: true, name: "ui_tppClientId"}
         </ext:options>
     </ext:dropIndex>

     <ext:dropIndex collectionName="createIndexNoOptionsTest">
         <ext:keys>
             { clientId: 1, type: 1}
         </ext:keys>
     </ext:dropIndex>
</changeSet>
  • insertMany inserts multiple documents into a collection.
<changeSet id="1" author="liquibase">
     <ext:insertMany collectionName="insertManyTest1">
         <ext:documents>
                [
                { id: 2 },
                { id: 3,
                  address: { nr: 1, ap: 5}
                }
                ]
         </ext:documents>
     </ext:insertMany>
</changeSet>
  • insertOne inserts a single document into a collection.
<changeSet id="1" author="liquibase">
    <ext:insertOne collectionName="insertOneTest1">
         <ext:document>
            {
                id: 111
            }
        </ext:document>
    </ext:insertOne>
</changeSet>

<changeSet id="2" author="liquibase">
    <ext:insertOne collectionName="insertOneTest2">
        <ext:document>
            {
                id: 2
            }
        </ext:document>
    </ext:insertOne>

    <ext:insertOne collectionName="insertOneTest3">
        <ext:document>
            { 
                id: 3
            }
        </ext:document>
    </ext:insertOne>
</changeSet>

<changeSet id="3" author="liquibase">
    <ext:insertOne collectionName="insertOneTest2">
        <ext:document>
            {
                id: 21323123
            }
        </ext:document>
    </ext:insertOne>

    <ext:insertOne collectionName="insertOneTest3">
        <ext:document>
            {
                id: 321321313
            }
        </ext:document>
    </ext:insertOne>
</changeSet>
  • runCommand provides a helper to run specified database commands. This is the preferred method to issue database commands as it provides a consistent interface between the shell and drivers.
<changeSet id="1" author="liquibase">
    <ext:runCommand>
        <ext:command>
               { buildInfo: 1 }
        </ext:command>
    </ext:runCommand>
</changeSet>

<changeSet id="2" author="liquibase">
    <ext:adminCommand>
        <ext:command>
               { buildInfo: 1 }
        </ext:command>
   </ext:adminCommand>
</changeSet>
  • adminCommand provides a helper to run specified database commands against the admin database.
<changeSet id="2" author="liquibase">
     <ext:adminCommand>
         <ext:command>
                { buildInfo: 1 }
         </ext:command>
    </ext:adminCommand>
</changeSet>

Related links


Last update: May 23, 2023
Created: April 26, 2023