{"id":2784,"date":"2017-02-20T11:54:11","date_gmt":"2017-02-20T19:54:11","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2784"},"modified":"2025-06-13T21:40:22","modified_gmt":"2025-06-14T04:40:22","slug":"migrate-mongodb-mongoose-couchbase-ottoman","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/","title":{"rendered":"Migrate from MongoDB Mongoose to Couchbase with Ottoman"},"content":{"rendered":"<p>When talking to Node.js developers, it is common to hear about NoSQL as the database of choice for development. JavaScript and JSON come hand in hand because after all JSON stands for JavaScript Object Notation. This is a format most common in document oriented databases which Node.js developers tend to use.<\/p>\n<p>A very popular stack of development technologies is the MongoDB, Express Framework, Angular, and Node.js (MEAN) stack, but similarly there is also the Couchbase, Express Framework, Angular, and Node.js (CEAN) stack. Now don&#8217;t get me wrong, every technology I listed is great, but when your applications need to scale and maintain their performance, you might have better luck with <a href=\"https:\/\/www.couchbase.com\" target=\"_blank\" rel=\"noopener noreferrer\">Couchbase<\/a> because of how it functions by design.<\/p>\n<p>So what if you&#8217;re already using MongoDB in your Node.js application?<\/p>\n<p>Chances are you&#8217;re using <a href=\"https:\/\/mongoosejs.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Mongoose<\/a> which is an Object Document Model (ODM) for interacting with the database. Couchbase also has an ODM and it is called <a href=\"https:\/\/www.ottomanjs.com\" target=\"_blank\" rel=\"noopener noreferrer\">Ottoman<\/a>. The great thing about these two ODM technologies is that they share pretty much the same set of APIs, making any transition incredibly easy.<\/p>\n<p>We&#8217;re going to see how to take advantage of MongoDB&#8217;s REST API to transition from a Node.js application using Mongoose and migrate it to Couchbase, featuring Ottoman.<\/p>\n<p><!--more--><\/p>\n<h2>The Requirements<\/h2>\n<p>This tutorial is going to be a little different because of all the technologies involved. We&#8217;re going to be building everything from scratch for simplicity, so the following are requirements and recommendations:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.couchbase.com\/downloads\/\" target=\"_blank\" rel=\"noopener noreferrer\">Couchbase Server<\/a> 4.5+<\/li>\n<li><a href=\"https:\/\/www.mongodb.com\/download-center\" target=\"_blank\" rel=\"noopener noreferrer\">MongoDB<\/a> 3.4+<\/li>\n<li><a href=\"https:\/\/nodejs.org\" target=\"_blank\" rel=\"noopener noreferrer\">Node.js<\/a> 6.0+<\/li>\n<\/ul>\n<p>We&#8217;re going to start by building a MongoDB REST API in Node.js using Mongoose, hence the Node.js and MongoDB requirement. Then we&#8217;re going to take this application and migrate it to Couchbase.<\/p>\n<p>For purposes of this example, we won&#8217;t be seeing how to configure Node.js, MongoDB, or Couchbase Server.<\/p>\n<h2>Understanding our NoSQL Data Model<\/h2>\n<p>Both MongoDB and Couchbase are document databases. One stores BSON data and the other stores JSON, however from the developer perspective they are incredibly similar. That said, let&#8217;s design a few models based around students attending courses at a school. The first model we create might be for actual courses, where a single course might look like the following:<\/p>\n<pre class=\"lang:default highlight:0 decode:true \" title=\"Courses NoSQL Document\">{\r\n    \"id\": \"course-1\",\r\n    \"type\": \"course\",\r\n    \"name\": \"Computer Science 101\",\r\n    \"term\": \"F2017\",\r\n    \"students\": [\r\n        \"student-1\",\r\n        \"student-2\"\r\n    ]\r\n}<\/pre>\n<p>In the above, notice that the course has a unique id, and we&#8217;ve defined it as being a course. The course has naming information as well as a list of students that are enrolled.<\/p>\n<p>Now let&#8217;s say we want to define our model for student documents:<\/p>\n<pre class=\"lang:default highlight:0 decode:true \" title=\"Students NoSQL Document\">{\r\n    \"id\": \"student-1\",\r\n    \"type\": \"student\",\r\n    \"firstname\": \"Nic\",\r\n    \"lastname\": \"Raboy\",\r\n    \"courses\": [\r\n        \"course-1\",\r\n        \"course-25\"\r\n    ]\r\n}<\/pre>\n<p>Notice that the above model has a similar format to that of the courses. What we&#8217;re saying here is that both documents are related, but still semi-structured. We&#8217;re saying that each course keeps track of its students and each student keeps track of their courses. This is useful when we try to query the data.<\/p>\n<p>There are unlimited possibilities when it comes to modeling your NoSQL data. In fact there are probably more than one hundred ways to define a &#8220;courses and students&#8221; model, versus what I had decided. It is totally up to you, and that is the flexibility that NoSQL brings. More information on data modeling can be found <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/data-modeling\/intro-data-modeling.html\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>.<\/p>\n<p>With a data model in mind, we can create a simple set of API endpoints using each MongoDB with Mongoose and Couchbase with Ottoman.<\/p>\n<h2>Developing an API with Express Framework and MongoDB<\/h2>\n<p>Because we are, in theory, migrating away from MongoDB to Couchbase, it would make sense to figure out what we want in a MongoDB application first.<\/p>\n<p>Create a new directory somewhere on your computer to represent the first part of our project. Within this directory, execute the following:<\/p>\n<pre class=\"lang:sh decode:true \" title=\"Create Mongoose and Node Project\">npm init --y\r\nnpm install express body-parser mongodb mongoose --save<\/pre>\n<p>The above commands will create a file called <strong>package.json<\/strong> that will keep track of each of the four project dependencies. The <code>express<\/code> dependency is for Express framework and the <code>body-parser<\/code> dependency allows for request bodies to exist in POST, PUT, and DELETE requests, all of which are common for altering data. Then <code>mongodb<\/code> and `mongoose` are required for working with the database.<\/p>\n<p>The project we build will have the following structure:<\/p>\n<pre class=\"lang:default highlight:0 decode:true \" title=\"Project Structure\">app.js\r\nroutes\/\r\n    courses.js\r\n    students.js\r\nmodels\/\r\n    models.js\r\npackage.json\r\nnode_modules\/<\/pre>\n<p>Go ahead and create those directories and files if they don&#8217;t already exist. The <strong>app.js<\/strong> file will be the application driver where as the <strong>routes<\/strong> will contain our API endpoints and the <strong>models<\/strong> will contain the database definitions for our application.<\/p>\n<h3>Defining the Mongoose Schemas<\/h3>\n<p>So let&#8217;s work backwards, starting with the Mongoose model that will communicate with MongoDB. Open the project&#8217;s <strong>models\/models.js<\/strong> file and include the following:<\/p>\n<pre class=\"lang:js decode:true \" title=\"Mongoose Schema\">var Mongoose = require(\"mongoose\");\r\nvar Schema = Mongoose.Schema;\r\nvar ObjectId = Mongoose.SchemaTypes.ObjectId;\r\n\r\nvar CourseSchema = new Mongoose.Schema({\r\n    name: String,\r\n    term: String,\r\n    students: [\r\n        {\r\n            type: ObjectId,\r\n            ref: StudentSchema\r\n        }\r\n    ]\r\n});\r\n\r\nvar StudentSchema = new Mongoose.Schema({\r\n    firstname: String,\r\n    lastname: String,\r\n    courses: [\r\n        {\r\n            type: ObjectId,\r\n            ref: CourseSchema\r\n        }\r\n    ]\r\n});\r\n\r\nmodule.exports.CourseModel = Mongoose.model(\"Course\", CourseSchema);\r\nmodule.exports.StudentModel = Mongoose.model(\"Student\", StudentSchema);<\/pre>\n<p>In the above we&#8217;re creating MongoDB document schemas and then creating models out of them. Notice how similar the schemas are to the JSON models that we had defined previously outside of the application. We&#8217;re not declaring an <code>id<\/code> and <code>type<\/code> because the ODM handles this for us. In each of the arrays we use a reference to another schema. What we&#8217;ll see at save is a document id, but we can leverage the querying technologies to load that id into actual data.<\/p>\n<p>So how do we use those models?<\/p>\n<h3>Creating the REST API Routes<\/h3>\n<p>Now we want to create routing information, or in other words, API endpoints. For example, let&#8217;s create all the CRUD endpoints for course information. In the project&#8217;s <strong>routes\/courses.js<\/strong> file, add the following:<\/p>\n<pre class=\"lang:js decode:true \" title=\"Course API Routes\">var CourseModel = require(\"..\/models\/models\").CourseModel;\r\n\r\nvar router = function(app) {\r\n\r\n    app.get(\"\/courses\", function(request, response) {\r\n        CourseModel.find({}).populate(\"students\").then(function(result) {\r\n            response.send(result);\r\n        }, function(error) {\r\n            response.status(401).send({ \"success\": false, \"message\": error});\r\n        });\r\n    });\r\n\r\n    app.get(\"\/course\/:id\", function(request, response) {\r\n        CourseModel.findOne({\"_id\": request.params.id}).populate(\"students\").then(function(result) {\r\n            response.send(result);\r\n        }, function(error) {\r\n            response.status(401).send({ \"success\": false, \"message\": error});\r\n        });\r\n    });\r\n\r\n    app.post(\"\/courses\", function(request, response) {\r\n        var course = new CourseModel({\r\n            \"name\": request.body.name\r\n        });\r\n        course.save(function(error, course) {\r\n            if(error) {\r\n                return response.status(401).send({ \"success\": false, \"message\": error});\r\n            }\r\n            response.send(course);\r\n        });\r\n    });\r\n\r\n}\r\n\r\nmodule.exports = router;<\/pre>\n<p>In the above example we have three endpoints. We can view all available courses, view courses by id, and create new courses. Each endpoint is powered by Mongoose.<\/p>\n<pre class=\"lang:js decode:true \" title=\"Endpoint for Creating Data\">app.post(\"\/courses\", function(request, response) {\r\n    var course = new CourseModel({\r\n        \"name\": request.body.name\r\n    });\r\n    course.save(function(error, course) {\r\n        if(error) {\r\n            return response.status(401).send({ \"success\": false, \"message\": error});\r\n        }\r\n        response.send(course);\r\n    });\r\n});<\/pre>\n<p>When creating a document, the request POST data is added to a new model instantiation. Once <code>save<\/code> is called, it gets saved to MongoDB. Similar things happen when reading data from the database.<\/p>\n<pre class=\"lang:js decode:true\" title=\"Get All Course Documents\">app.get(\"\/courses\", function(request, response) {\r\n    CourseModel.find({}).populate(\"students\").then(function(result) {\r\n        response.send(result);\r\n    }, function(error) {\r\n        response.status(401).send({ \"success\": false, \"message\": error});\r\n    });\r\n});<\/pre>\n<p>In the case of the above, the <code>find<\/code> function is called and parameters are passed in. When there are no parameters, then all documents are returned from the <code>Course<\/code> collection, otherwise data is queried by the properties passed. The <code>populate<\/code> function allows the document references to be loaded so instead of returning id values back, the actual documents are returned.<\/p>\n<p>Now let&#8217;s take a look at the other route.<\/p>\n<p>The second route is responsible for creating student data, but there is an exception here. We&#8217;re also going to be managing the document relationships here. Open the project&#8217;s <strong>routes\/students.js<\/strong> file and include the following source code:<\/p>\n<pre class=\"lang:js decode:true\" title=\"Student API Endpoints\">var CourseModel = require(\"..\/models\/models\").CourseModel;\r\nvar StudentModel = require(\"..\/models\/models\").StudentModel;\r\n\r\nvar router = function(app) {\r\n\r\n    app.get(\"\/students\", function(request, response) {\r\n        StudentModel.find({}).populate(\"courses\").then(function(result) {\r\n            response.send(result);\r\n        }, function(error) {\r\n            response.status(401).send({ \"success\": false, \"message\": error});\r\n        });\r\n    });\r\n\r\n    app.get(\"\/student\/:id\", function(request, response) {\r\n        StudentModel.findOne({\"_id\": request.params.id}).populate(\"courses\").then(function(result) {\r\n            response.send(result);\r\n        }, function(error) {\r\n            response.status(401).send({ \"success\": false, \"message\": error});\r\n        });\r\n    });\r\n\r\n    app.post(\"\/students\", function(request, response) {\r\n        var student = new StudentModel({\r\n            \"firstname\": request.body.firstname,\r\n            \"lastname\": request.body.lastname\r\n        });\r\n        student.save(function(error, student) {\r\n            if(error) {\r\n                return response.status(401).send({ \"success\": false, \"message\": error});\r\n            }\r\n            response.send(student);\r\n        });\r\n    });\r\n\r\n    app.post(\"\/student\/course\", function(request, response) {\r\n        CourseModel.findOne({\"_id\": request.body.course_id}).then(function(course) {\r\n            StudentModel.findOne({\"_id\": request.body.student_id}).then(function(student) {\r\n                if(course != null &amp;&amp; student != null) {\r\n                    if(!student.courses) {\r\n                        student.courses = [];\r\n                    }\r\n                    if(!course.students) {\r\n                        course.students = [];\r\n                    }\r\n                    student.courses.push(course._id);\r\n                    course.students.push(student._id);\r\n                    student.save();\r\n                    course.save();\r\n                    response.send(student);\r\n                } else {\r\n                    return response.status(401).send({ \"success\": false, \"message\": \"The `student_id` or `course_id` was invalid\"});\r\n                }\r\n            }, function(error) {\r\n                return response.status(401).send({ \"success\": false, \"message\": error});\r\n            });\r\n        }, function(error) {\r\n            return response.status(401).send({ \"success\": false, \"message\": error});\r\n        });\r\n    });\r\n\r\n}\r\n\r\nmodule.exports = router;<\/pre>\n<p>The first three API endpoints should look familiar. The new endpoint <code>student\/course<\/code> is responsible for adding students to a course and courses to a student.<\/p>\n<p>The first thing that happens is a course is found based on a request id. Next, a student is found based on a different request id. If both documents are found then the ids are added to each of the appropriate arrays and the documents are saved once again.<\/p>\n<p>The final step here is to create our application driver. This will connect to the database and serve the application to be consumed by clients.<\/p>\n<h3>Connecting to MongoDB and Serving the Application<\/h3>\n<p>Open the project&#8217;s <strong>app.js<\/strong> file and add the following code:<\/p>\n<pre class=\"lang:js decode:true \" title=\"app.js\">var Mongoose = require(\"mongoose\");\r\nvar Express = require(\"express\");\r\nvar BodyParser = require(\"body-parser\");\r\n\r\nvar app = Express();\r\napp.use(BodyParser.json());\r\n\r\nMongoose.Promise = Promise;\r\nvar studentRoutes = require(\".\/routes\/students\")(app);\r\nvar courseRoutes = require(\".\/routes\/courses\")(app);\r\nMongoose.connect(\"mongodb:\/\/localhost:27017\/example\", function(error, database) {\r\n    if(error) {\r\n        return console.log(\"Could not establish a connection to MongoDB\");\r\n    }\r\n    var server = app.listen(3000, function() {\r\n        console.log(\"Connected on port 3000...\");\r\n    });\r\n});<\/pre>\n<p>In the above code we are importing each of the dependencies that we previously installed. Then we are initializing Express and telling it to accept JSON bodies in requests.<\/p>\n<p>The routes that were previously created need to be linked to Express, so we&#8217;re importing them and passing the Express instance. Finally, a connection to MongoDB is made with Mongoose and the application starts serving.<\/p>\n<p>Not particularly difficult right?<\/p>\n<h2>Developing an API with Express Framework and Couchbase<\/h2>\n<p>So we saw how to create an API with Node.js, Mongoose, and MongoDB, so now we need to accomplish the same thing with Node.js, Ottoman, and Couchbase. Again this is to show how easy it is to transition from MongoDB to Couchbase and get all the benefits of an Enterprise ready, powerful NoSQL database.<\/p>\n<p>Create a new directory somewhere on your computer and within it, execute the following to create a new project:<\/p>\n<pre class=\"lang:sh decode:true \" title=\"Create New Couchbase with Node Project\">npm init --y\r\nnpm install express body-parser couchbase ottoman --save<\/pre>\n<p>The above commands are similar to what we saw previously, with the exception that now we&#8217;re using Couchbase and Ottoman. The project we build will have exactly the same structure, and as a refresher, it looks like the following:<\/p>\n<pre class=\"lang:default highlight:0 decode:true\" title=\"Node Project Structure\">app.js\r\nroutes\/\r\n    courses.js\r\n    students.js\r\nmodels\/\r\n    models.js\r\npackage.json\r\nnode_modules\/<\/pre>\n<p>All Ottoman models will exist in the <strong>models<\/strong> directory, all API endpoints and Ottoman logic will exist in the <strong>routes<\/strong> directory and all driver logic will exist in the <strong>app.js<\/strong> file.<\/p>\n<h3>Defining the Ottoman Models<\/h3>\n<p>We&#8217;re going to work in the same direction that we did for the MongoDB application to show the ease of transition. This means starting with the Ottoman models that will represent our data in Couchbase Server.<\/p>\n<p>Open the project&#8217;s <strong>models\/models.js<\/strong> file and include the following:<\/p>\n<pre class=\"lang:js decode:true\" title=\"models\/models.js\">var Ottoman = require(\"ottoman\");\r\n\r\nvar CourseModel = Ottoman.model(\"Course\", {\r\n    name: { type: \"string\" },\r\n    term: { type: \"string\" },\r\n    students: [\r\n        {\r\n            ref: \"Student\"\r\n        }\r\n    ]\r\n});\r\n\r\nvar StudentModel = Ottoman.model(\"Student\", {\r\n    firstname: { type: \"string\" },\r\n    lastname: { type: \"string\" },\r\n    courses: [\r\n        {\r\n            ref: \"Course\"\r\n        }\r\n    ]\r\n});\r\n\r\nmodule.exports.StudentModel = StudentModel;\r\nmodule.exports.CourseModel = CourseModel;<\/pre>\n<p>The above should look familiar, yet you have to realize that these are two very different ODMs. Instead of designing MongoDB schemas through Mongoose we can go straight to designing JSON models for Couchbase with Ottoman. Remember there are no schemas in Couchbase Buckets.<\/p>\n<p>Each Ottoman model has a set of properties and an array referencing other documents. While the syntax is slightly different, it accomplishes the same thing.<\/p>\n<p>This brings us to the API endpoints that use these models.<\/p>\n<h3>Creating the REST API Endpoints<\/h3>\n<p>The first set of endpoints that we want to create are in relation to managing courses. Open the project&#8217;s <strong>routes\/courses.js<\/strong> file and include the following JavaScript code:<\/p>\n<pre class=\"lang:js decode:true\" title=\"routes\/courses.js\">var CourseModel = require(\"..\/models\/models\").CourseModel;\r\n\r\nvar router = function(app) {\r\n\r\n    app.get(\"\/courses\", function(request, response) {\r\n        CourseModel.find({}, {load: [\"students\"]}, function(error, result) {\r\n            if(error) {\r\n                return response.status(401).send({ \"success\": false, \"message\": error});\r\n            }\r\n            response.send(result);\r\n        });\r\n    });\r\n\r\n    app.get(\"\/course\/:id\", function(request, response) {\r\n        CourseModel.getById(request.params.id, {load: [\"students\"]}, function(error, result) {\r\n            if(error) {\r\n                return response.status(401).send({ \"success\": false, \"message\": error});\r\n            }\r\n            response.send(result);\r\n        });\r\n    });\r\n\r\n    app.post(\"\/courses\", function(request, response) {\r\n        var course = new CourseModel({\r\n            \"name\": request.body.name\r\n        });\r\n        course.save(function(error, result) {\r\n            if(error) {\r\n                return response.status(401).send({ \"success\": false, \"message\": error});\r\n            }\r\n            response.send(course);\r\n        });\r\n    });\r\n\r\n}\r\n\r\nmodule.exports = router;<\/pre>\n<p>In the above code we have three endpoints structured in a near identical way to what we saw with MongoDB and Mongoose. However, there are some minor differences. For example, instead of using promises we&#8217;re using callbacks.<\/p>\n<p>One of the more visible differences is how querying is done. Not only do we have access to a <code>find<\/code> function like we saw in Mongoose, but we also have access to a <code>getById<\/code> function. In both scenarios we can pass information on how we expect a query to happen. Instead of using a <code>populate<\/code> function we can use <code>load<\/code> and provide which reference documents we wish to load. The concepts between Mongoose and Ottoman are very much the same.<\/p>\n<p>This brings us to our second set of routes. Open the project&#8217;s <strong>routes\/students.js<\/strong> file and include the following JavaScript code:<\/p>\n<pre class=\"lang:js decode:true\" title=\"routes\/students.js\">var StudentModel = require(\"..\/models\/models\").StudentModel;\r\nvar CourseModel = require(\"..\/models\/models\").CourseModel;\r\n\r\nvar router = function(app) {\r\n\r\n    app.get(\"\/students\", function(request, response) {\r\n        StudentModel.find({}, {load: [\"courses\"]}, function(error, result) {\r\n            if(error) {\r\n                return response.status(401).send({ \"success\": false, \"message\": error});\r\n            }\r\n            response.send(result);\r\n        });\r\n    });\r\n\r\n    app.get(\"\/student\/:id\", function(request, response) {\r\n        StudentModel.getById(request.params.id, {load: [\"courses\"]}, function(error, result) {\r\n            if(error) {\r\n                return response.status(401).send({ \"success\": false, \"message\": error});\r\n            }\r\n            response.send(result);\r\n        });\r\n    });\r\n\r\n    app.post(\"\/students\", function(request, response) {\r\n        var student = new StudentModel({\r\n            \"firstname\": request.body.firstname,\r\n            \"lastname\": request.body.lastname\r\n        });\r\n        student.save(function(error, result) {\r\n            if(error) {\r\n                return response.status(401).send({ \"success\": false, \"message\": error});\r\n            }\r\n            response.send(student);\r\n        });\r\n    });\r\n\r\n    app.post(\"\/student\/course\", function(request, response) {\r\n        CourseModel.getById(request.body.course_id, function(error, course) {\r\n            if(error) {\r\n                return response.status(401).send({ \"success\": false, \"message\": error});\r\n            }\r\n            StudentModel.getById(request.body.student_id, function(error, student) {\r\n                if(error) {\r\n                    return response.status(401).send({ \"success\": false, \"message\": error});\r\n                }\r\n                if(!student.courses) {\r\n                    student.courses = [];\r\n                }\r\n                if(!course.students) {\r\n                    course.students = [];\r\n                }\r\n                student.courses.push(CourseModel.ref(course._id));\r\n                course.students.push(StudentModel.ref(student._id));\r\n                student.save(function(error, result) {});\r\n                course.save(function(error, result) {});\r\n                response.send(student);\r\n            });\r\n        });\r\n    })\r\n}\r\n\r\nmodule.exports = router;<\/pre>\n<p>We already know the first three endpoints are going to be of the same format. We want to pay attention to the last endpoint which manages our relationships.<\/p>\n<p>With this endpoint we are obtaining a course by its id value and a student based on its id value. As long as both return a document, we can add a reference of each to each of their arrays and re-save the document. The same thing and nearly the same code was found in the Mongoose version.<\/p>\n<p>Now we can look at the logic to start serving the application after connecting to the database.<\/p>\n<h3>Connecting to Couchbase and Serving the Application<\/h3>\n<p>Open the project&#8217;s <strong>app.js<\/strong> file and include the following JavaScript:<\/p>\n<pre class=\"lang:js decode:true\" title=\"app.js\">var Couchbase = require(\"couchbase\");\r\nvar Ottoman = require(\"ottoman\");\r\nvar Express = require(\"express\");\r\nvar BodyParser = require(\"body-parser\");\r\n\r\nvar app = Express();\r\napp.use(BodyParser.json());\r\n\r\nvar bucket = (new Couchbase.Cluster(\"couchbase:\/\/localhost\")).openBucket(\"example\");\r\nOttoman.store = new Ottoman.CbStoreAdapter(bucket, Couchbase);\r\nvar studentRoutes = require(\".\/routes\/students\")(app);\r\nvar courseRoutes = require(\".\/routes\/courses\")(app);\r\nvar server = app.listen(3000, function() {\r\n    console.log(\"Connected on port 3000...\");\r\n});<\/pre>\n<p>Does the above look familiar? It should! We are just swapping out the Mongoose connection information with the Couchbase connection information. After connecting to the database we can start serving the application.<\/p>\n<h2>Conclusion<\/h2>\n<p><span style=\"font-weight: 400\">Migration from Mongoose and MongoDB is easier than you might think. In fact, y<\/span>ou just saw how to build a REST API with Node.js, Mongoose, and MongoDB, then bring it to Couchbase in a very seamless fashion. This was meant to prove that the migration process is nothing to be scared about, especially if you&#8217;re using Node.js as your backend technology.<\/p>\n<p>With Couchbase you have a high-performance, distributed NoSQL database that works at any scale. The need to use caching in front of your database is eliminated because it is built into Couchbase. For more information on using Ottoman, you can check out a <a href=\"https:\/\/www.couchbase.com\/blog\/easily-develop-node.js-and-couchbase-apps-with-ottoman\/\" target=\"_blank\" rel=\"noopener noreferrer\">previous blog<\/a> post I wrote. More information on using Couchbase with Node.js can be found in the <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/sdk\/nodejs\/start-using-sdk.html\" target=\"_blank\" rel=\"noopener noreferrer\">Couchbase Developer Portal<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When talking to Node.js developers, it is common to hear about NoSQL as the database of choice for development. JavaScript and JSON come hand in hand because after all JSON stands for JavaScript Object Notation. This is a format most [&hellip;]<\/p>\n","protected":false},"author":63,"featured_media":2787,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1816,9327,1822,10128],"tags":[1393,1254,1543,1309,1746,1745],"ppma_author":[9032],"class_list":["post-2784","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-server","category-javascript","category-node-js","category-ottoman","tag-api","tag-express","tag-javascript","tag-mongodb","tag-mongoose","tag-restful"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.8 (Yoast SEO v25.8) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Migrate from MongoDB Mongoose to Couchbase with Ottoman<\/title>\n<meta name=\"description\" content=\"Learn how to migrate your Mongoose and MongoDB powered Node.js application to a faster and more scalable Ottoman and Couchbase powered solution.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Migrate from MongoDB Mongoose to Couchbase with Ottoman\" \/>\n<meta property=\"og:description\" content=\"Learn how to migrate your Mongoose and MongoDB powered Node.js application to a faster and more scalable Ottoman and Couchbase powered solution.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/thepolyglotdeveloper\" \/>\n<meta property=\"article:published_time\" content=\"2017-02-20T19:54:11+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T04:40:22+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/mongo-to-couchbase.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1100\" \/>\n\t<meta property=\"og:image:height\" content=\"389\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@nraboy\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/\"},\"author\":{\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\"},\"headline\":\"Migrate from MongoDB Mongoose to Couchbase with Ottoman\",\"datePublished\":\"2017-02-20T19:54:11+00:00\",\"dateModified\":\"2025-06-14T04:40:22+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/\"},\"wordCount\":1998,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/mongo-to-couchbase.png\",\"keywords\":[\"API\",\"express\",\"javascript\",\"mongodb\",\"mongoose\",\"restful\"],\"articleSection\":[\"Couchbase Server\",\"JavaScript\",\"Node.js\",\"Ottoman.js ODM\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/\",\"name\":\"Migrate from MongoDB Mongoose to Couchbase with Ottoman\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/mongo-to-couchbase.png\",\"datePublished\":\"2017-02-20T19:54:11+00:00\",\"dateModified\":\"2025-06-14T04:40:22+00:00\",\"description\":\"Learn how to migrate your Mongoose and MongoDB powered Node.js application to a faster and more scalable Ottoman and Couchbase powered solution.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/mongo-to-couchbase.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/mongo-to-couchbase.png\",\"width\":1100,\"height\":389},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Migrate from MongoDB Mongoose to Couchbase with Ottoman\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\",\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/8863514d8bed0cf6080f23db40e00354\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"caption\":\"Nic Raboy, Developer Advocate, Couchbase\"},\"description\":\"Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.\",\"sameAs\":[\"https:\/\/www.thepolyglotdeveloper.com\",\"https:\/\/www.facebook.com\/thepolyglotdeveloper\",\"https:\/\/x.com\/nraboy\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/nic-raboy-2\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Migrate from MongoDB Mongoose to Couchbase with Ottoman","description":"Learn how to migrate your Mongoose and MongoDB powered Node.js application to a faster and more scalable Ottoman and Couchbase powered solution.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/","og_locale":"en_US","og_type":"article","og_title":"Migrate from MongoDB Mongoose to Couchbase with Ottoman","og_description":"Learn how to migrate your Mongoose and MongoDB powered Node.js application to a faster and more scalable Ottoman and Couchbase powered solution.","og_url":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/","og_site_name":"The Couchbase Blog","article_author":"https:\/\/www.facebook.com\/thepolyglotdeveloper","article_published_time":"2017-02-20T19:54:11+00:00","article_modified_time":"2025-06-14T04:40:22+00:00","og_image":[{"width":1100,"height":389,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/mongo-to-couchbase.png","type":"image\/png"}],"author":"Nic Raboy, Developer Advocate, Couchbase","twitter_card":"summary_large_image","twitter_creator":"@nraboy","twitter_misc":{"Written by":"Nic Raboy, Developer Advocate, Couchbase","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/"},"author":{"name":"Nic Raboy, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1"},"headline":"Migrate from MongoDB Mongoose to Couchbase with Ottoman","datePublished":"2017-02-20T19:54:11+00:00","dateModified":"2025-06-14T04:40:22+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/"},"wordCount":1998,"commentCount":2,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/mongo-to-couchbase.png","keywords":["API","express","javascript","mongodb","mongoose","restful"],"articleSection":["Couchbase Server","JavaScript","Node.js","Ottoman.js ODM"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/","url":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/","name":"Migrate from MongoDB Mongoose to Couchbase with Ottoman","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/mongo-to-couchbase.png","datePublished":"2017-02-20T19:54:11+00:00","dateModified":"2025-06-14T04:40:22+00:00","description":"Learn how to migrate your Mongoose and MongoDB powered Node.js application to a faster and more scalable Ottoman and Couchbase powered solution.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/mongo-to-couchbase.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/mongo-to-couchbase.png","width":1100,"height":389},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-mongoose-couchbase-ottoman\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Migrate from MongoDB Mongoose to Couchbase with Ottoman"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1","name":"Nic Raboy, Developer Advocate, Couchbase","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/8863514d8bed0cf6080f23db40e00354","url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","caption":"Nic Raboy, Developer Advocate, Couchbase"},"description":"Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.","sameAs":["https:\/\/www.thepolyglotdeveloper.com","https:\/\/www.facebook.com\/thepolyglotdeveloper","https:\/\/x.com\/nraboy"],"url":"https:\/\/www.couchbase.com\/blog\/author\/nic-raboy-2\/"}]}},"authors":[{"term_id":9032,"user_id":63,"is_guest":0,"slug":"nic-raboy-2","display_name":"Nic Raboy, Developer Advocate, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","author_category":"","last_name":"Raboy","first_name":"Nic","job_title":"","user_url":"https:\/\/www.thepolyglotdeveloper.com","description":"Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/2784","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/63"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=2784"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/2784\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/2787"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=2784"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=2784"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=2784"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=2784"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}