{"id":2918,"date":"2017-03-07T11:11:30","date_gmt":"2017-03-07T19:11:30","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2918"},"modified":"2025-06-13T17:33:05","modified_gmt":"2025-06-14T00:33:05","slug":"migrate-mongodb-couchbase-n1ql","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/migrate-mongodb-couchbase-n1ql\/","title":{"rendered":"Migrar do MongoDB para o Couchbase com o N1QL"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">Os clientes frequentemente nos dizem que est\u00e3o se preparando para migrar do MongoDB para o Couchbase. Em parte, eles v\u00eam porque est\u00e3o cansados dos problemas que tiveram ao aprender a consultar o MongoDB. O Couchbase com N1QL oferece uma alternativa melhor, especialmente para o dimensionamento de aplicativos modernos.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Infelizmente, com o MongoDB, as op\u00e7\u00f5es de migra\u00e7\u00e3o podem ser limitadas. Uma delas, sobre a qual escrevi recentemente, envolve a mudan\u00e7a de<\/span> de <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/migrating-mongodb-mongoose-restful-api-couchbase-ottoman\/\" target=\"_blank\" rel=\"noopener noreferrer\">MongoDB com Mongoose para Couchbase com Ottoman<\/a>.  O ponto central desse tutorial foi o uso de duas ferramentas ODM diferentes no Node.js que compartilhavam as mesmas APIs, tornando a transi\u00e7\u00e3o quase perfeita.  No entanto, e se voc\u00ea n\u00e3o estiver usando um ODM no MongoDB e n\u00e3o tiver interesse em usar um?<\/p>\n<p>Desta vez, vamos dar uma olhada na transfer\u00eancia de um aplicativo Node.js que usa o MongoDB e a linguagem de consulta do MongoDB para o Couchbase com o N1QL.  Em resumo, o N1QL \u00e9 uma tecnologia que permite que voc\u00ea execute consultas SQL em dados JSON complexos.  Isso a torna n\u00e3o apenas f\u00e1cil de usar, mas tamb\u00e9m muito limpa na camada de aplicativos.  Mais informa\u00e7\u00f5es sobre o N1QL podem ser encontradas na se\u00e7\u00e3o <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/4.6\/getting-started\/try-a-query.html\" target=\"_blank\" rel=\"noopener noreferrer\">Portal do desenvolvedor do Couchbase<\/a>.<\/p>\n<p><!--more--><\/p>\n<p>Vamos usar o mesmo problema de exemplo usado no <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/migrating-mongodb-mongoose-restful-api-couchbase-ottoman\/\" target=\"_blank\" rel=\"noopener noreferrer\">Artigo anterior<\/a>mas n\u00e3o h\u00e1 problema se voc\u00ea ainda n\u00e3o o viu.  Tudo aqui ser\u00e1 iniciado com uma lousa limpa.<\/p>\n<h2>Os requisitos<\/h2>\n<p>H\u00e1 alguns requisitos que devem ser atendidos para garantir que voc\u00ea tenha sucesso com este guia.  Eles podem ser vistos a seguir:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\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:\/\/www.couchbase.com\/blog\/pt\/downloads\/\" target=\"_blank\" rel=\"noopener noreferrer\">Couchbase<\/a> 4.5+<\/li>\n<li><a href=\"https:\/\/nodejs.org\/en\/\" target=\"_blank\" rel=\"noopener noreferrer\">Node.js<\/a> 6.0+<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Como veremos os equivalentes do MongoDB e do Couchbase, voc\u00ea deve ter os dois bancos de dados dispon\u00edveis.  Se j\u00e1 for um desenvolvedor do MongoDB, muitas coisas podem ser familiares para voc\u00ea, mas a decis\u00e3o \u00e9 sua.<\/p>\n<h2>Entendendo o modelo de dados NoSQL<\/h2>\n<p>Antes de desenvolver a API RESTful com qualquer uma das tecnologias, \u00e9 uma boa ideia entender primeiro o modelo de dados que ser\u00e1 usado.<\/p>\n<p>Embora o MongoDB e o Couchbase sejam bancos de dados de documentos, eles n\u00e3o s\u00e3o totalmente iguais.  O MongoDB armazena dados como BSON, enquanto o Couchbase armazena dados como JSON.  Do ponto de vista da modelagem, isso realmente n\u00e3o importa para n\u00f3s.<\/p>\n<p>Considere o modelo de dados de uma escola em que voc\u00ea tem alunos e cursos.  Para cada curso oferecido na escola, voc\u00ea pode ter um documento parecido com o seguinte:<\/p>\n<pre class=\"lang:default highlight:0 decode:true\" title=\"Modelo NoSQL para cursos\">{\r\n    \"id\": \"course-1\",\r\n    \"type\" (tipo): \"course\" (curso),\r\n    \"name\" (nome): \"Ci\u00eancia da Computa\u00e7\u00e3o 101\",\r\n    \"termo\": \"F2017\",\r\n    \"alunos\": [\r\n        \"student-1\",\r\n        \"student-2\"\r\n    ]\r\n}<\/pre>\n<p>Cada curso manter\u00e1 uma lista de todos os alunos que foram registrados.  Nesse caso, a lista consistir\u00e1 em valores de id que fazem refer\u00eancia a outros documentos.  Estamos estabelecendo nossas pr\u00f3prias rela\u00e7\u00f5es de documentos.<\/p>\n<p>Para cada aluno da escola, eles podem ter um documento NoSQL parecido com o seguinte:<\/p>\n<pre class=\"lang:default highlight:0 decode:true\" title=\"Modelo NoSQL para estudantes\">{\r\n    \"id\": \"student-1\",\r\n    \"type\" (tipo): \"student\",\r\n    \"firstname\": \"Nic\",\r\n    \"lastname\": \"Raboy\",\r\n    \"courses\": [\r\n        \"curso-1\",\r\n        \"curso-25\"\r\n    ]\r\n}<\/pre>\n<p>Observe que o documento acima \u00e9 semelhante \u00e0 forma como modelamos nossos cursos.  Cada aluno manter\u00e1 uma lista de todos os cursos em que est\u00e1 matriculado.  Esses cursos s\u00e3o IDs que fazem refer\u00eancia ao documento apropriado do curso.<\/p>\n<p>H\u00e1 centenas de maneiras diferentes de modelar nossos documentos, e este \u00e9 apenas um exemplo.  Para obter mais informa\u00e7\u00f5es sobre modelagem de dados, d\u00ea uma olhada em <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/data-modeling\/intro-data-modeling.html\" target=\"_blank\" rel=\"noopener noreferrer\">documenta\u00e7\u00e3o<\/a>.<\/p>\n<p>Agora que temos um modelo para nossos documentos, podemos nos concentrar na cria\u00e7\u00e3o de uma API com cada tecnologia.<\/p>\n<h2>Desenvolvimento de uma API com a linguagem de consulta do MongoDB<\/h2>\n<p>Embora voc\u00ea possa ter seu pr\u00f3prio c\u00f3digo de aplicativo MongoDB, vamos criar um do zero para que a migra\u00e7\u00e3o permane\u00e7a muito f\u00e1cil de entender.<\/p>\n<p>Vamos come\u00e7ar criando um novo projeto em nosso prompt de comando ou terminal:<\/p>\n<pre class=\"lang:sh decode:true\">npm init --y\r\nnpm install express body-parser mongodb --save<\/pre>\n<p>Os comandos acima criar\u00e3o um novo\u00a0<strong>package.json<\/strong> em seu diret\u00f3rio de trabalho atual e instale as depend\u00eancias necess\u00e1rias da estrutura e do banco de dados.<\/p>\n<p>No final das contas, queremos que nosso projeto MongoDB tenha a seguinte estrutura:<\/p>\n<pre class=\"lang:default highlight:0 decode:true\">app.js\r\nrotas\/\r\n    cursos.js\r\n    alunos.js\r\nmodelos\/\r\n    aluno.js\r\n    curso.js\r\npackage.json\r\nnode_modules\/<\/pre>\n<p>Toda a intera\u00e7\u00e3o com o banco de dados ser\u00e1 feita a partir de cada um dos <strong>modelos<\/strong> e todo o roteamento de API e a intera\u00e7\u00e3o com o cliente ser\u00e3o feitos a partir do\u00a0<strong>rotas<\/strong> arquivos.  A inicializa\u00e7\u00e3o do aplicativo e a conex\u00e3o com o banco de dados ser\u00e3o feitas a partir do arquivo\u00a0<strong>app.js<\/strong> arquivo.<\/p>\n<h3>Cria\u00e7\u00e3o de um modelo de banco de dados MongoDB no aplicativo<\/h3>\n<p>Ent\u00e3o, vamos dar uma olhada em um dos nossos modelos de banco de dados.  Abra a se\u00e7\u00e3o\u00a0<strong>models\/course.js<\/strong> e inclua o seguinte c\u00f3digo:<\/p>\n<pre class=\"lang:js decode:true\">var Database = require(\"..\/..\/app\").database;\r\nvar ObjectId = require(\"mongodb\").ObjectId;\r\n\r\nfunction CourseModel() { };\r\n\r\nCourseModel.save = function(data, callback) {\r\n    Database.collection(\"courses\").insertOne(data, function(error, result) {\r\n        if(error) {\r\n            return callback(error, null);\r\n        }\r\n        callback(null, result);\r\n    });\r\n}\r\n\r\nCourseModel.updateStudents = function(id, students, callback) {\r\n    Database.collection(\"courses\").updateOne({ \"_id\": new ObjectId(id) },\r\n        {\r\n            $set: { \"students\": students }\r\n        }, function(error, result) {\r\n            if(error) {\r\n                return callback(error, null);\r\n            }\r\n            callback(null, result);\r\n        }\r\n    );\r\n}\r\n\r\nCourseModel.getById = function(documentId, callback) {\r\n    var cursor = Database.collection(\"courses\").aggregate([\r\n        { \"$match\": { \"_id\": new ObjectId(documentId) } },\r\n        { \"$unwind\": { \"path\": \"$students\", \"preserveNullAndEmptyArrays\": true } },\r\n        {\r\n            \"$lookup\": {\r\n                \"from\": \"students\",\r\n                \"localField\": \"students\",\r\n                \"foreignField\": \"_id\",\r\n                \"as\": \"studentObjects\"\r\n            }\r\n        },\r\n        { \"$unwind\": { \"path\": \"$studentObjects\", \"preserveNullAndEmptyArrays\": true} },\r\n        { \"$group\": {\r\n            \"_id\": {\r\n                \"_id\": \"$_id\",\r\n                \"name\": \"$name\"\r\n            },\r\n            \"students\": { \"$push\": \"$studentObjects\" }\r\n        }},\r\n        {\r\n            \"$project\": {\r\n                \"_id\": \"$_id._id\",\r\n                \"name\": \"$_id.name\",\r\n                \"students\": \"$students\"\r\n            }\r\n        },\r\n        { \"$limit\": 1 }\r\n    ]);\r\n    cursor.toArray(callback);\r\n};\r\n\r\nCourseModel.getAll = function(callback) {\r\n    var cursor = Database.collection(\"courses\").aggregate([\r\n        { \"$unwind\": { \"path\": \"$students\", \"preserveNullAndEmptyArrays\": true} },\r\n        {\r\n            \"$lookup\": {\r\n                \"from\": \"students\",\r\n                \"localField\": \"students\",\r\n                \"foreignField\": \"_id\",\r\n                \"as\": \"studentObjects\"\r\n            }\r\n        },\r\n        { \"$unwind\": { \"path\": \"$studentObjects\", \"preserveNullAndEmptyArrays\": true} },\r\n        { \"$group\": {\r\n            \"_id\": {\r\n                \"_id\": \"$_id\",\r\n                \"name\": \"$name\"\r\n            },\r\n            \"students\": { \"$push\": \"$studentObjects\" }\r\n        }},\r\n        {\r\n            \"$project\": {\r\n                \"_id\": \"$_id._id\",\r\n                \"name\": \"$_id.name\",\r\n                \"students\": \"$students\"\r\n            }\r\n        }\r\n    ]);\r\n    cursor.toArray(callback);\r\n};\r\n\r\nmodule.exports = CourseModel;<\/pre>\n<p>H\u00e1 muita coisa acontecendo no modelo de banco de dados acima.  Precisamos dividi-lo para facilitar a compreens\u00e3o.  Quanto mais entendermos, mais f\u00e1cil ser\u00e1 o processo de migra\u00e7\u00e3o para o Couchbase.<\/p>\n<p>Quando desejamos salvar um documento, temos a op\u00e7\u00e3o\u00a0<code>salvar<\/code> m\u00e9todo:<\/p>\n<pre class=\"lang:js decode:true\">CourseModel.save = function(data, callback) {\r\n    Database.collection(\"courses\").insertOne(data, function(error, result) {\r\n        if(error) {\r\n            return callback(error, null);\r\n        }\r\n        callback(null, result);\r\n    });\r\n}<\/pre>\n<p>Usando o banco de dados aberto, podemos inserir um \u00fanico documento na cole\u00e7\u00e3o desejada usando o comando\u00a0<code>insertOne<\/code> function.  Nessa fun\u00e7\u00e3o, passamos\u00a0<code>dados<\/code> que pode ser um objeto JavaScript de qualquer complexidade que desejamos salvar.  Depois de salvo, o resultado ser\u00e1 retornado ao m\u00e9todo pai que o chamou.<\/p>\n<p>E se quisermos atualizar um documento que j\u00e1 existe?  Em particular, e se quisermos adicionar um aluno a um curso j\u00e1 existente?<\/p>\n<p>Para este exemplo espec\u00edfico, podemos atualizar todo o\u00a0<code>estudantes<\/code> que existe no documento:<\/p>\n<pre class=\"lang:js decode:true\">CourseModel.updateStudents = function(id, students, callback) {\r\n    Database.collection(\"courses\").updateOne({ \"_id\": new ObjectId(id) },\r\n        {\r\n            $set: { \"students\": students }\r\n        }, function(error, result) {\r\n            if(error) {\r\n                return callback(error, null);\r\n            }\r\n            callback(null, result);\r\n        }\r\n    );\r\n}<\/pre>\n<p>O c\u00f3digo acima usar\u00e1 o\u00a0<code>updateOne<\/code> para pesquisar um determinado documento por id e substituir o m\u00e9todo\u00a0<code>estudantes<\/code> com uma nova matriz que fornecemos por meio do\u00a0<code>updateStudents<\/code> fun\u00e7\u00e3o.<\/p>\n<p>Nada muito dif\u00edcil at\u00e9 agora e nenhum estresse real adicionado ao desenvolvedor.<\/p>\n<p>\u00c9 aqui que as coisas mudam.  Quando salvamos os dados, estamos salvando uma matriz de valores de id.  Esses n\u00e3o s\u00e3o dados que queremos ver nas opera\u00e7\u00f5es de consulta.  Em vez disso, queremos preencher ou expandir esses valores de id em seus equivalentes de documento:<\/p>\n<pre class=\"lang:js decode:true\">CourseModel.getAll = function(callback) {\r\n    var cursor = Database.collection(\"courses\").aggregate([\r\n        { \"$unwind\": { \"path\": \"$students\", \"preserveNullAndEmptyArrays\": true} },\r\n        {\r\n            \"$lookup\": {\r\n                \"from\": \"students\",\r\n                \"localField\": \"students\",\r\n                \"foreignField\": \"_id\",\r\n                \"as\": \"studentObjects\"\r\n            }\r\n        },\r\n        { \"$unwind\": { \"path\": \"$studentObjects\", \"preserveNullAndEmptyArrays\": true} },\r\n        { \"$group\": {\r\n            \"_id\": {\r\n                \"_id\": \"$_id\",\r\n                \"name\": \"$name\"\r\n            },\r\n            \"students\": { \"$push\": \"$studentObjects\" }\r\n        }},\r\n        {\r\n            \"$project\": {\r\n                \"_id\": \"$_id._id\",\r\n                \"name\": \"$_id.name\",\r\n                \"students\": \"$students\"\r\n            }\r\n        }\r\n    ]);\r\n    cursor.toArray(callback);\r\n};<\/pre>\n<p>Para que isso seja poss\u00edvel, a matriz deve primeiro ser achatada por meio de um\u00a0<code>$unwind<\/code> e unidos por meio de um\u00a0<code>$lookup<\/code> opera\u00e7\u00e3o.  E n\u00e3o para por a\u00ed, pois queremos que nossos resultados sejam formatados da mesma forma, apenas substituindo os ids por objetos.  Por isso, temos que fazer mais achatamentos, agrupamentos e manipula\u00e7\u00f5es.<\/p>\n<p>Uma explica\u00e7\u00e3o completa sobre a uni\u00e3o de dados no MongoDB versus a uni\u00e3o de dados no Couchbase pode ser vista em um <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/joining-nosql-documents-mongodb-query-language-vs-couchbase-n1ql\/\" target=\"_blank\" rel=\"noopener noreferrer\">artigo completo que escrevi anteriormente<\/a> sobre o assunto.<\/p>\n<p>Resumindo, quanto mais complicados forem seus dados, mais complicada ser\u00e1 sua consulta de agrega\u00e7\u00e3o.  Para um modelo de dados flex\u00edvel, isso se torna pouco flex\u00edvel para um desenvolvedor de aplicativos.<\/p>\n<p>Vamos dar uma olhada r\u00e1pida em nosso outro modelo, aquele que gerenciar\u00e1 os dados dos alunos.  Abra a se\u00e7\u00e3o\u00a0<strong>models\/student.js<\/strong> e inclua o seguinte c\u00f3digo JavaScript:<\/p>\n<pre class=\"lang:js decode:true\">var Database = require(\"..\/..\/app\").database;\r\nvar ObjectId = require(\"mongodb\").ObjectId;\r\n\r\nfunction StudentModel() { };\r\n\r\nStudentModel.save = function(data, callback) {\r\n    Database.collection(\"students\").insertOne(data, function(error, result) {\r\n        if(error) {\r\n            return callback(error, null);\r\n        }\r\n        callback(null, result);\r\n    });\r\n}\r\n\r\nStudentModel.updateCourses = function(id, courses, callback) {\r\n    Database.collection(\"students\").updateOne({ \"_id\": new ObjectId(id) },\r\n        {\r\n            $set: { \"courses\": courses }\r\n        }, function(error, result) {\r\n            if(error) {\r\n                return callback(error, null);\r\n            }\r\n            callback(null, result);\r\n        }\r\n    );\r\n}\r\n\r\nStudentModel.getById = function(documentId, callback) {\r\n    var cursor = Database.collection(\"students\").aggregate([\r\n        { \"$match\": { \"_id\": new ObjectId(documentId) } },\r\n        { \"$unwind\": { \"path\": \"$courses\", \"preserveNullAndEmptyArrays\": true } },\r\n        {\r\n            \"$lookup\": {\r\n                \"from\": \"courses\",\r\n                \"localField\": \"courses\",\r\n                \"foreignField\": \"_id\",\r\n                \"as\": \"courseObjects\"\r\n            }\r\n        },\r\n        { \"$unwind\": { \"path\": \"$courseObjects\", \"preserveNullAndEmptyArrays\": true } },\r\n        { \"$group\": {\r\n            \"_id\": {\r\n                \"_id\": \"$_id\",\r\n                \"name\": \"$name\"\r\n            },\r\n            \"courses\" (cursos): { \"$push\": \"$courseObjects\" }\r\n        }},\r\n        {\r\n            \"$project\": {\r\n                \"_id\": \"$_id._id\",\r\n                \"name\": \"$_id.name\",\r\n                \"courses\" (cursos): \"$courses\"\r\n            }\r\n        },\r\n        { \"$limit\": 1 }\r\n    ]);\r\n    cursor.toArray(callback);\r\n};\r\n\r\nStudentModel.getAll = function(callback) {\r\n    var cursor = Database.collection(\"students\").aggregate([\r\n        { \"$unwind\": { \"path\": \"$courses\", \"preserveNullAndEmptyArrays\": true } },\r\n        {\r\n            \"$lookup\": {\r\n                \"from\": \"courses\",\r\n                \"localField\": \"courses\",\r\n                \"foreignField\": \"_id\",\r\n                \"as\": \"courseObjects\"\r\n            }\r\n        },\r\n        { \"$unwind\": { \"path\": \"$courseObjects\", \"preserveNullAndEmptyArrays\": true } },\r\n        { \"$group\": {\r\n            \"_id\": {\r\n                \"_id\": \"$_id\",\r\n                \"firstname\": \"$firstname\",\r\n                \"lastname\": \"$lastname\",\r\n                \"address\" (endere\u00e7o): \"$address\"\r\n            },\r\n            \"courses\" (cursos): { \"$push\": \"$courseObjects\" }\r\n        }},\r\n        {\r\n            \"$project\": {\r\n                \"_id\": \"$_id._id\",\r\n                \"firstname\": \"$_id.firstname\",\r\n                \"lastname\": \"$_id.lastname\",\r\n                \"address\" (endere\u00e7o): \"$_id.address\",\r\n                \"courses\" (cursos): \"$courses\"\r\n            }\r\n        }\r\n    ]);\r\n    cursor.toArray(callback);\r\n};\r\n\r\nmodule.exports = StudentModel;<\/pre>\n<p>Praticamente as mesmas regras se aplicam ao modelo acima em compara\u00e7\u00e3o com o modelo que vimos representando os dados do curso.  Isso se deve ao fato de que os dois modelos de documento eram muito semelhantes no in\u00edcio.  Na maior parte, s\u00e3o planos, com uma matriz de valores de id.<\/p>\n<p>Isso nos leva aos pontos de extremidade da API que fazem uso desses m\u00e9todos de banco de dados.<\/p>\n<h3>Cria\u00e7\u00e3o de rotas de API RESTful para o aplicativo<\/h3>\n<p>Essa \u00e9 a parte f\u00e1cil e, na verdade, a mais consistente entre as duas tecnologias de banco de dados, pois n\u00e3o depende do banco de dados.<\/p>\n<p>Vamos dar uma olhada no projeto\u00a0<strong>rotas\/cursos.js<\/strong> file:<\/p>\n<pre class=\"lang:js decode:true\">var CourseModel = require(\"..\/models\/course\");\r\n\r\nvar router = function(app) {\r\n\r\n    app.get(\"\/courses\", function(request, response) {\r\n        CourseModel.getAll(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, 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[0]);\r\n        });\r\n    });\r\n\r\n    app.post(\"\/courses\", function(request, response) {\r\n        se(!request.body.name) {\r\n            return response.status(401).send({\"success\": false, \"message\": \"A `name` is required\"});\r\n        }\r\n        CourseModel.save(request.body, 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>No c\u00f3digo acima, temos tr\u00eas rotas de API.  A partir de um cliente externo, poderemos listar todos os cursos, localizar um curso espec\u00edfico ou salvar um novo curso.<\/p>\n<p>Dependendo de qual endpoint for atingido, a fun\u00e7\u00e3o apropriada do modelo de banco de dados ser\u00e1 executada.  N\u00e3o \u00e9 feito muito trabalho pesado nas rotas, que, com base em seu nome, destinam-se apenas ao roteamento.<\/p>\n<p>O outro arquivo de roteamento ser\u00e1 um pouco diferente.  Abra o arquivo\u00a0<strong>routes\/students.js<\/strong> e inclua o seguinte c\u00f3digo JavaScript:<\/p>\n<pre class=\"lang:js decode:true\">var StudentModel = require(\"..\/models\/student\");\r\nvar CourseModel = require(\"..\/models\/course\");\r\n\r\nvar router = function(app) {\r\n\r\n    app.get(\"\/students\", function(request, response) {\r\n        StudentModel.getAll(function(error, result) {\r\n            if(error) {\r\n                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, function(error, result) {\r\n            if(error) {\r\n                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        se(!request.body.firstname) {\r\n            return response.status(401).send({\"success\": false, \"message\": \"A `firstname` is required\"});\r\n        } else if(!request.body.lastname) {\r\n            return response.status(401).send({\"success\": false, \"message\": \"A `lastname` is required\"});\r\n        } else if(!request.body.address) {\r\n            return response.status(401).send({ \"success\": false, \"message\": \"An `address` is required\"});\r\n        }\r\n        StudentModel.save(request.body, 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        se(!request.body.student_id) {\r\n            return response.status(401).send({ \"success\": false, \"message\": \"A `student_id` is required\" });\r\n        } else if(!request.body.course_id) {\r\n            return response.status(401).send({ \"success\": false, \"message\": \"A `course_id` is required\" });\r\n        }\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(course != null &amp;&amp; student != null) {\r\n                    se(!aluno[0].cursos) {\r\n                        student[0].courses = [];\r\n                    }\r\n                    if(!course[0].students) {\r\n                        course[0].students = [];\r\n                    }\r\n                    var cursos = [];\r\n                    var alunos = [];\r\n                    for(var i = 0; i &lt; student[0].courses.length; i++) {\r\n                        courses.push(student[0].courses[i]._id);\r\n                    }\r\n                    for(var i = 0; i &lt; course[0].students.length; i++) {\r\n                        students.push(course[0].students[i]._id);\r\n                    }\r\n                    courses.push(course[0]._id);\r\n                    students.push(student[0]._id);\r\n                    StudentModel.updateCourses(student[0]._id, courses, function(error, result) {});\r\n                    CourseModel.updateStudents(course[0]._id, students, function(error, result) {});\r\n                    response.send(student[0]);\r\n                } else {\r\n                    return response.status(401).send({&quot;success&quot;: false, &quot;message&quot;: &quot;The `student_id` or `course_id` was invalid&quot;});\r\n                }\r\n            });\r\n        });\r\n    });\r\n\r\n}\r\n\r\nmodule.exports = router;<\/pre>\n<p>Como na outra rota, h\u00e1 muita coisa acontecendo, mas a maior parte \u00e9 praticamente id\u00eantica.  As diferen\u00e7as est\u00e3o na\u00a0<code>\/estudante\/curso<\/code> que \u00e9 respons\u00e1vel por adicionar cursos a um aluno e alunos a um curso.<\/p>\n<p>Ao acessar esse endpoint, primeiro obtemos as informa\u00e7\u00f5es do aluno e do curso com base no valor de id passado.  Ambos precisam existir, caso contr\u00e1rio, lan\u00e7aremos um erro.  Se ambos existirem, enviaremos o ID do aluno para a vari\u00e1vel\u00a0<code>estudantes<\/code> para o documento do curso e o ID do curso na matriz\u00a0<code>cursos<\/code> do documento do aluno.  Em seguida, chamaremos nosso m\u00e9todo de atualiza\u00e7\u00e3o e retornaremos um resultado para o usu\u00e1rio final.<\/p>\n<h3>Reunindo tudo e inicializando o aplicativo<\/h3>\n<p>Neste ponto, a API est\u00e1 pronta para ser usada.  S\u00f3 precisamos inicializar o aplicativo Node.js e nos conectar ao banco de dados.  Essa \u00e9 a parte mais f\u00e1cil.<\/p>\n<p>Abra o arquivo\u00a0<strong>app.js<\/strong> e inclua o seguinte c\u00f3digo:<\/p>\n<pre class=\"lang:js decode:true\">var MongoClient = require(\"mongodb\").MongoClient;\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\nMongoClient.connect(\"mongodb:\/\/localhost:27017\/example\", function(error, database) {\r\n    if(error) {\r\n        return console.log(\"N\u00e3o foi poss\u00edvel estabelecer uma conex\u00e3o com o MongoDB\");\r\n    }\r\n    module.exports.database = banco de dados;\r\n    var studentRoutes = require(\".\/mongodb\/routes\/students\")(app);\r\n    var courseRoutes = require(\".\/mongodb\/routes\/courses\")(app);\r\n    var server = app.listen(3000, function() {\r\n        console.log(\"Conectado na porta 3000...\");\r\n    });\r\n});<\/pre>\n<p>No c\u00f3digo acima, estamos importando cada uma das depend\u00eancias que baixamos e inicializando o Express Framework.  Antes de come\u00e7armos a servir a API, precisamos estabelecer uma conex\u00e3o com o MongoDB.  Depois que a conex\u00e3o \u00e9 estabelecida, as rotas s\u00e3o conectadas e o aplicativo come\u00e7a a servir.<\/p>\n<p>Nesse ponto, a API RESTful pode ser acessada em https:\/\/localhost:3000 e testada com ferramentas populares como <a href=\"https:\/\/www.thepolyglotdeveloper.com\/2015\/01\/using-postman-troubleshoot-restful-api-requests\/\" target=\"_blank\" rel=\"noopener noreferrer\">Carteiro<\/a> ou Fiddler.<\/p>\n<h2>Desenvolvimento de uma API com Couchbase e N1QL<\/h2>\n<p>Portanto, temos um exemplo com o qual trabalhar quando se trata de MongoDB e Node.js.  Esse exemplo usou a linguagem de consulta do MongoDB ao se comunicar com o banco de dados.<\/p>\n<p>Agora, vamos pegar esse aplicativo e mov\u00ea-lo para <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/\" target=\"_blank\" rel=\"noopener noreferrer\">Couchbase<\/a>.  Estamos fazendo isso porque, al\u00e9m de o Couchbase ser mais escalon\u00e1vel e ter melhor desempenho, a linguagem de consulta \u00e9 muito mais simples e f\u00e1cil de manter em um aplicativo.<\/p>\n<p>Assim como no aplicativo MongoDB, vamos come\u00e7ar do zero, embora muito do que veremos seja id\u00eantico.  No prompt de comando ou no terminal, execute o seguinte:<\/p>\n<pre class=\"lang:sh highlight:0 decode:true\">npm init --y\r\nnpm install express body-parser couchbase --save<\/pre>\n<p>Os comandos acima devem parecer familiares.  Estamos criando um arquivo\u00a0<strong>package.json<\/strong> e instalando nossas depend\u00eancias, mas, em vez do MongoDB, estamos usando o Couchbase.<\/p>\n<p>O projeto ter\u00e1 a mesma estrutura vista no projeto anterior.  Ele deve ter a seguinte apar\u00eancia:<\/p>\n<pre class=\"lang:default highlight:0 decode:true\">app.js\r\nrotas\/\r\n    cursos.js\r\n    alunos.js\r\nmodelos\/\r\n    curso.js\r\n    aluno.js\r\npackage.json\r\nnode_modules\/<\/pre>\n<p>A mesma l\u00f3gica vista anteriormente terminar\u00e1 em cada um desses arquivos.  A diferen\u00e7a \u00e9 a sintaxe do Couchbase.<\/p>\n<h3>Cria\u00e7\u00e3o de um modelo de banco de dados do Couchbase no aplicativo<\/h3>\n<p>Come\u00e7ando com a mesma ordem, vamos criar nossas fun\u00e7\u00f5es de modelo de banco de dados.  Conforme mencionado anteriormente, usaremos o N1QL, que \u00e9 um destaque extremo do Couchbase, pois permite que voc\u00ea escreva consultas SQL.  Essas consultas s\u00e3o executadas no banco de dados e n\u00e3o no aplicativo Node.js.<\/p>\n<p>Abra o arquivo\u00a0<strong>models\/course.js<\/strong> e inclua o seguinte c\u00f3digo:<\/p>\n<pre class=\"lang:js decode:true\">var Uuid = require(\"uuid\");\r\nvar Bucket = require(\"..\/..\/app\").bucket;\r\nvar N1qlQuery = require(\"couchbase\").N1qlQuery;\r\n\r\nfun\u00e7\u00e3o CourseModel() { };\r\n\r\nCourseModel.save = function(data, callback) {\r\n    data.id = Uuid.v4();\r\n    data.type = \"course\";\r\n    data.students = [];\r\n    var statement = \"INSERT INTO `\" + Bucket._name + \"` (KEY, VALUE) VALUES ($1, $2) RETURNING `\" + Bucket._name + \"`.*\";\r\n    var query = N1qlQuery.fromString(statement);\r\n    Bucket.query(query, [data.id, data], function(error, result) {\r\n        if(error) {\r\n            callback(error, null);\r\n            return;\r\n        }\r\n        callback(null, result);\r\n    });\r\n}\r\n\r\nCourseModel.updateStudents = function(id, courses, callback) {\r\n    var statement = \"UPDATE `\" + Bucket._name + \"` USE KEYS $1 SET students = $2 RETURNING `\" + Bucket._name + \"`.*\";\r\n    var query = N1qlQuery.fromString(statement);\r\n    Bucket.query(query, [id, courses], function(error, result) {\r\n        if(error) {\r\n            callback(error, null);\r\n            return;\r\n        }\r\n        callback(null, result);\r\n    });\r\n}\r\n\r\nCourseModel.getById = function(documentId, callback) {\r\n    var statement = \"SELECT s.id, s.type, s.name, \" +\r\n                    \"(SELECT t.* FROM `\" + Bucket._name + \"` AS t USE KEYS s.students) AS students \" +\r\n                    \"FROM `\" + Bucket._name + \"` AS s \" +\r\n                    \"WHERE s.type = 'course' AND s.id = $1\";\r\n    var query = N1qlQuery.fromString(statement);\r\n    Bucket.query(query, [documentId], function(error, result) {\r\n        if(error) {\r\n            return callback(error, null);\r\n        }\r\n        callback(null, result);\r\n    });\r\n};\r\n\r\nCourseModel.getAll = function(callback) {\r\n    var statement = \"SELECT s.id, s.type, s.name, \" +\r\n                    \"(SELECT t.* FROM `\" + Bucket._name + \"` AS t USE KEYS s.students) AS students \" +\r\n                    \"FROM `\" + Bucket._name + \"` AS s \" +\r\n                    \"WHERE s.type = 'course'\";\r\n    var query = N1qlQuery.fromString(statement).consistency(N1qlQuery.Consistency.REQUEST_PLUS);\r\n    Bucket.query(query, function(error, result) {\r\n        if(error) {\r\n            return callback(error, null);\r\n        }\r\n        callback(null, result);\r\n    });\r\n};\r\n\r\nmodule.exports = CourseModel;<\/pre>\n<p>No c\u00f3digo acima, temos o mesmo conjunto de fun\u00e7\u00f5es relacionadas ao banco de dados que vimos no exemplo do MongoDB.  Dentro de cada uma dessas fun\u00e7\u00f5es h\u00e1 consultas N1QL.  N\u00e3o apenas consultas N1QL, mas consultas N1QL parametrizadas para ajudar a combater ataques de inje\u00e7\u00e3o de SQL.<\/p>\n<p>D\u00ea uma olhada no\u00a0<code>getAll<\/code> que antes era muito complicado na vers\u00e3o do MongoDB:<\/p>\n<pre class=\"lang:js decode:true\">CourseModel.getAll = function(callback) {\r\n    var statement = \"SELECT s.id, s.type, s.name, \" +\r\n                    \"(SELECT t.* FROM `\" + Bucket._name + \"` AS t USE KEYS s.students) AS students \" +\r\n                    \"FROM `\" + Bucket._name + \"` AS s \" +\r\n                    \"WHERE s.type = 'course'\";\r\n    var query = N1qlQuery.fromString(statement).consistency(N1qlQuery.Consistency.REQUEST_PLUS);\r\n    Bucket.query(query, function(error, result) {\r\n        if(error) {\r\n            return callback(error, null);\r\n        }\r\n        callback(null, result);\r\n    });\r\n};<\/pre>\n<p>Desta vez, temos uma consulta simples que inclui uma subconsulta.  Se nossas necessidades de dados se tornarem mais complexas, a consulta poder\u00e1 ser alterada sem aumentar significativamente o tamanho ou a complexidade.<\/p>\n<p>Ent\u00e3o, vamos dar uma olhada em nosso outro modelo de banco de dados.  Abra a se\u00e7\u00e3o\u00a0<strong>models\/student.js<\/strong> e inclua o seguinte c\u00f3digo JavaScript:<\/p>\n<pre class=\"lang:js decode:true\">var Uuid = require(\"uuid\");\r\nvar Bucket = require(\"..\/..\/app\").bucket;\r\nvar N1qlQuery = require(\"couchbase\").N1qlQuery;\r\n\r\nfun\u00e7\u00e3o StudentModel() { };\r\n\r\nStudentModel.save = function(data, callback) {\r\n    data.id = Uuid.v4();\r\n    data.type = \"student\";\r\n    data.courses = [];\r\n    var statement = \"INSERT INTO `\" + Bucket._name + \"` (KEY, VALUE) VALUES ($1, $2) RETURNING `\" + Bucket._name + \"`.*\";\r\n    var query = N1qlQuery.fromString(statement);\r\n    Bucket.query(query, [data.id, data], function(error, result) {\r\n        if(error) {\r\n            callback(error, null);\r\n            return;\r\n        }\r\n        callback(null, result);\r\n    });\r\n}\r\n\r\nStudentModel.updateCourses = function(id, courses, callback) {\r\n    var statement = \"UPDATE `\" + Bucket._name + \"` USE KEYS $1 SET courses = $2 RETURNING `\" + Bucket._name + \"`.*\";\r\n    var query = N1qlQuery.fromString(statement);\r\n    Bucket.query(query, [id, courses], function(error, result) {\r\n        if(error) {\r\n            callback(error, null);\r\n            return;\r\n        }\r\n        callback(null, result);\r\n    });\r\n}\r\n\r\nStudentModel.getById = function(documentId, callback) {\r\n    var statement = \"SELECT t.id, t.type, t.firstname, t.lastname, t.address, \" +\r\n                    \"(SELECT s.* FROM `\" + Bucket._name + \"` AS s USE KEYS t.courses) AS courses \" +\r\n                    \"FROM `\" + Bucket._name + \"` AS t \" +\r\n                    \"WHERE t.type = 'student' AND t.id = $1\";\r\n    var query = N1qlQuery.fromString(statement);\r\n    Bucket.query(query, [documentId], function(error, result) {\r\n        if(error) {\r\n            console.log(error);\r\n            return callback(error, null);\r\n        }\r\n        callback(null, result);\r\n    });\r\n};\r\n\r\nStudentModel.getAll = function(callback) {\r\n    var statement = \"SELECT t.id, t.type, t.firstname, t.lastname, t.address, \" +\r\n                    \"(SELECT s.* FROM `\" + Bucket._name + \"` AS s USE KEYS t.courses) AS courses \" +\r\n                    \"FROM `\" + Bucket._name + \"` AS t \" +\r\n                    \"WHERE t.type = 'student'\";\r\n    var query = N1qlQuery.fromString(statement).consistency(N1qlQuery.Consistency.REQUEST_PLUS);\r\n    Bucket.query(query, function(error, result) {\r\n        if(error) {\r\n            return callback(error, null);\r\n        }\r\n        callback(null, result);\r\n    });\r\n};\r\n\r\nmodule.exports = StudentModel;<\/pre>\n<p>Parece familiar?  Os dois modelos de banco de dados s\u00e3o semelhantes porque os dois modelos de documentos s\u00e3o semelhantes.  Novamente, se a complexidade mudar, a camada do aplicativo ainda ser\u00e1 f\u00e1cil de gerenciar com consultas N1QL.<\/p>\n<p>Como as rotas de API n\u00e3o t\u00eam nenhuma depend\u00eancia do banco de dados, o c\u00f3digo entre o aplicativo MongoDB e o aplicativo Couchbase pode ser compartilhado.  Para ser claro, estou me referindo aos arquivos encontrados no diret\u00f3rio\u00a0<strong>rotas<\/strong> diret\u00f3rio.<\/p>\n<h3>Inicializa\u00e7\u00e3o do aplicativo e conex\u00e3o com o Couchbase<\/h3>\n<p>Com os pontos de extremidade instalados e os modelos de banco de dados se comunicando com o Couchbase por meio do N1QL, podemos concluir o aplicativo.<\/p>\n<p>Abra o arquivo\u00a0<strong>app.js<\/strong> e inclua o seguinte c\u00f3digo JavaScript:<\/p>\n<pre class=\"lang:js decode:true\">var Couchbase = require(\"couchbase\");\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\nmodule.exports.bucket = (new Couchbase.Cluster(\"couchbase:\/\/localhost\")).openBucket(\"example\");\r\nvar studentRoutes = require(\".\/couchbase\/routes\/students\")(app);\r\nvar courseRoutes = require(\".\/couchbase\/routes\/courses\")(app);\r\nvar server = app.listen(3000, function() {\r\n    console.log(\"Conectado na porta 3000...\");\r\n});<\/pre>\n<p>No c\u00f3digo acima, estamos importando as depend\u00eancias que instalamos e inicializando o Express Framework.  Em seguida, estamos estabelecendo uma conex\u00e3o com o banco de dados, reunindo nossas rotas e iniciando o servidor Node.js.<\/p>\n<p>Como estamos usando o N1QL, n\u00e3o se esque\u00e7a de criar pelo menos um \u00edndice no seu Couchbase Bucket.  Ele pode ser t\u00e3o simples quanto o seguinte:<\/p>\n<pre class=\"lang:default highlight:0 decode:true\">CREATE PRIMARY INDEX ON `example`;<\/pre>\n<p>Neste ponto, voc\u00ea deve conseguir acessar seu aplicativo da mesma forma que o MongoDB.  Visite https:\/\/localhost:3000 em seu navegador da Web ou com uma ferramenta como Postman ou Fiddler.<\/p>\n<h2>Conclus\u00e3o<\/h2>\n<p>Voc\u00ea acabou de ver como pegar um aplicativo Node.js que usa o MongoDB e a linguagem de consulta do MongoDB e convert\u00ea-lo para o Couchbase com o N1QL.  Essa \u00e9 uma alternativa ao m\u00e9todo <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/migrating-mongodb-mongoose-restful-api-couchbase-ottoman\/\" target=\"_blank\" rel=\"noopener noreferrer\">ODM de mangusto para otomano<\/a> sobre a qual escrevi anteriormente.<\/p>\n<p>Ent\u00e3o, por que voc\u00ea quer mudar do MongoDB para o Couchbase?  Bem, o Couchbase \u00e9 muito mais r\u00e1pido e f\u00e1cil de escalonar, mas o N1QL tamb\u00e9m \u00e9 incrivelmente simples quando se trabalha com dados complexos.  Voc\u00ea poder\u00e1 reduzir drasticamente seu c\u00f3digo e mant\u00ea-lo mais sustent\u00e1vel.  Confira a consulta Couchbase vs. MongoDB <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/joining-nosql-documents-mongodb-query-language-vs-couchbase-n1ql\/\" target=\"_blank\" rel=\"noopener noreferrer\">tutorial<\/a> Escrevi sobre a uni\u00e3o de dados entre os dois bancos de dados.<\/p>\n<p>Para obter mais informa\u00e7\u00f5es sobre como usar o Couchbase em um aplicativo Node.js:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Confira o <a href=\"https:\/\/developer.couchbase.com\" target=\"_blank\" rel=\"noopener noreferrer\">Portal do desenvolvedor do Couchbase<\/a>.<\/li>\n<li>Experimente um dos <a href=\"https:\/\/docs.couchbase.com\/server\/current\/develop\/integrations.html#ide-integrations\">IDEs para desenvolvedores do Couchbase - JetBrains, VSCode<\/a>para os quais temos plug-ins.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>","protected":false},"excerpt":{"rendered":"<p>Customers often tell us they\u2019re preparing to migrate from MongoDB to Couchbase. They come, in part, because they\u2019re tired of the problems they\u2019ve experienced learning how to query MongoDB. Couchbase with N1QL provides a better alternative, especially for scaling up [&hellip;]<\/p>","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":[1815,1816,1822,1812],"tags":[1393,1309,1745],"ppma_author":[9032],"class_list":["post-2918","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-best-practices-and-tutorials","category-couchbase-server","category-node-js","category-n1ql-query","tag-api","tag-mongodb","tag-restful"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Migrate From MongoDB to Couchbase with N1QL - The Couchbase Blog<\/title>\n<meta name=\"description\" content=\"Learn how to take a Node.js application that uses MongoDB and the MongoDB Query Language and convert it to Couchbase with N1QL instead.\" \/>\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\/pt\/migrate-mongodb-couchbase-n1ql\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Migrate From MongoDB to Couchbase with N1QL\" \/>\n<meta property=\"og:description\" content=\"Learn how to take a Node.js application that uses MongoDB and the MongoDB Query Language and convert it to Couchbase with N1QL instead.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/migrate-mongodb-couchbase-n1ql\/\" \/>\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-03-07T19:11:30+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T00:33:05+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=\"10 minutos\" \/>\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-couchbase-n1ql\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/\"},\"author\":{\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\"},\"headline\":\"Migrate From MongoDB to Couchbase with N1QL\",\"datePublished\":\"2017-03-07T19:11:30+00:00\",\"dateModified\":\"2025-06-14T00:33:05+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/\"},\"wordCount\":2176,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/mongo-to-couchbase.png\",\"keywords\":[\"API\",\"mongodb\",\"restful\"],\"articleSection\":[\"Best Practices and Tutorials\",\"Couchbase Server\",\"Node.js\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/\",\"name\":\"Migrate From MongoDB to Couchbase with N1QL - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/mongo-to-couchbase.png\",\"datePublished\":\"2017-03-07T19:11:30+00:00\",\"dateModified\":\"2025-06-14T00:33:05+00:00\",\"description\":\"Learn how to take a Node.js application that uses MongoDB and the MongoDB Query Language and convert it to Couchbase with N1QL instead.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/#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-couchbase-n1ql\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Migrate From MongoDB to Couchbase with N1QL\"}]},{\"@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\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@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\":\"pt-BR\",\"@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\/pt\/author\/nic-raboy-2\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Migrate From MongoDB to Couchbase with N1QL - The Couchbase Blog","description":"Learn how to take a Node.js application that uses MongoDB and the MongoDB Query Language and convert it to Couchbase with N1QL instead.","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\/pt\/migrate-mongodb-couchbase-n1ql\/","og_locale":"pt_BR","og_type":"article","og_title":"Migrate From MongoDB to Couchbase with N1QL","og_description":"Learn how to take a Node.js application that uses MongoDB and the MongoDB Query Language and convert it to Couchbase with N1QL instead.","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/migrate-mongodb-couchbase-n1ql\/","og_site_name":"The Couchbase Blog","article_author":"https:\/\/www.facebook.com\/thepolyglotdeveloper","article_published_time":"2017-03-07T19:11:30+00:00","article_modified_time":"2025-06-14T00:33:05+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":"10 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/"},"author":{"name":"Nic Raboy, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1"},"headline":"Migrate From MongoDB to Couchbase with N1QL","datePublished":"2017-03-07T19:11:30+00:00","dateModified":"2025-06-14T00:33:05+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/"},"wordCount":2176,"commentCount":1,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/mongo-to-couchbase.png","keywords":["API","mongodb","restful"],"articleSection":["Best Practices and Tutorials","Couchbase Server","Node.js","SQL++ \/ N1QL Query"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/","url":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/","name":"Migrate From MongoDB to Couchbase with N1QL - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/mongo-to-couchbase.png","datePublished":"2017-03-07T19:11:30+00:00","dateModified":"2025-06-14T00:33:05+00:00","description":"Learn how to take a Node.js application that uses MongoDB and the MongoDB Query Language and convert it to Couchbase with N1QL instead.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/migrate-mongodb-couchbase-n1ql\/#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-couchbase-n1ql\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Migrate From MongoDB to Couchbase with N1QL"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"Blog do Couchbase","description":"Couchbase, o banco de dados NoSQL","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":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@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, defensor dos desenvolvedores, Couchbase","image":{"@type":"ImageObject","inLanguage":"pt-BR","@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 \u00e9 um defensor das modernas tecnologias de desenvolvimento m\u00f3vel e da Web. Ele tem experi\u00eancia em Java, JavaScript, Golang e uma variedade de estruturas, como Angular, NativeScript e Apache Cordova. Nic escreve sobre suas experi\u00eancias de desenvolvimento relacionadas a tornar o desenvolvimento m\u00f3vel e da Web mais f\u00e1cil de entender.","sameAs":["https:\/\/www.thepolyglotdeveloper.com","https:\/\/www.facebook.com\/thepolyglotdeveloper","https:\/\/x.com\/nraboy"],"url":"https:\/\/www.couchbase.com\/blog\/pt\/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","first_name":"Nic","last_name":"Raboy","user_url":"https:\/\/www.thepolyglotdeveloper.com","author_category":"","description":"Nic Raboy \u00e9 um defensor das modernas tecnologias de desenvolvimento m\u00f3vel e da Web. Ele tem experi\u00eancia em Java, JavaScript, Golang e uma variedade de estruturas, como Angular, NativeScript e Apache Cordova. Nic escreve sobre suas experi\u00eancias de desenvolvimento relacionadas a tornar o desenvolvimento m\u00f3vel e da Web mais f\u00e1cil de entender."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2918","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/63"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=2918"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2918\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/2787"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=2918"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=2918"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=2918"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=2918"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}