{"id":10947,"date":"2021-03-30T09:13:45","date_gmt":"2021-03-30T16:13:45","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=10947"},"modified":"2025-06-13T23:42:25","modified_gmt":"2025-06-14T06:42:25","slug":"introduction-to-ottoman-with-couchbase","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/introduction-to-ottoman-with-couchbase\/","title":{"rendered":"Introdu\u00e7\u00e3o ao Ottoman com o Couchbase"},"content":{"rendered":"<p><span style=\"font-weight: 400\">O Ottoman \u00e9 um Object Data Modeler (ODM) para o SDK Node.js do Couchbase que fornece esquema e valida\u00e7\u00e3o JSON para NoSQL.<\/span><\/p>\n<h2>Por que usar um ODM para o Couchbase<\/h2>\n<p><span style=\"font-weight: 400\">Com o Ottoman, voc\u00ea declara o esquema em seu c\u00f3digo. Embora o Couchbase n\u00e3o tenha imposi\u00e7\u00e3o de esquema para seus documentos, a maioria dos aplicativos precisa de algum n\u00edvel de esquema, mesmo no NoSQL. Vamos explorar como obter o esquema e a valida\u00e7\u00e3o no NoSQL usando o Ottoman e o Couchbase. <\/span><\/p>\n<p><span style=\"font-weight: 400\">\u00c9 importante validar se os documentos atendem a determinados requisitos antes de persistir. Embora o Ottoman crie uma abstra\u00e7\u00e3o sobre o SDK do Couchbase, as vantagens superam as desvantagens. Um desenvolvedor cria muita l\u00f3gica para criar e atualizar documentos, escrever o ciclo de vida pr\u00e9\/p\u00f3s, trabalhar com estruturas de dados e valida\u00e7\u00e3o.<\/span><\/p>\n<h3>Banco de dados NoSQL e projeto de esquema<\/h3>\n<p class=\"q-text qu-display--block\">Um ODM desempenha uma fun\u00e7\u00e3o semelhante no NoSQL e em um banco de dados relacional, mas com benef\u00edcios adicionais. O Couchbase n\u00e3o imp\u00f5e valida\u00e7\u00e3o, pois \u00e9 flex\u00edvel em termos de esquema. O Ottoman pode realizar determinadas verifica\u00e7\u00f5es \u00e0 medida que seus aplicativos persistem nos dados. Podemos advertir e errar contra tipos e formatos de dados indesejados para campos individuais, definindo esquemas e modelos para v\u00e1rios tipos de documentos.<\/p>\n<p class=\"q-text qu-display--block\">O c\u00f3digo do aplicativo do servidor \u00e9 um \u00f3timo lugar para aplicar l\u00f3gica e valida\u00e7\u00e3o de neg\u00f3cios. <span style=\"font-weight: 400\">O objetivo do Ottoman \u00e9 proporcionar uma melhor experi\u00eancia de desenvolvimento, al\u00e9m de oferecer controle sobre o esquema e a valida\u00e7\u00e3o ao usar o Couchbase com o Node. Queremos oferecer aos desenvolvedores uma ferramenta confi\u00e1vel para criar sistemas que sejam f\u00e1ceis de projetar, manter e dimensionar.<\/span><\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/03\/Intro-Ottoman-One.gif\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-10948\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/03\/Intro-Ottoman-One.gif\" alt=\"Object Data Mapping in Node.js with Ottoman for Couchbase\" width=\"1371\" height=\"703\" \/><\/a><\/p>\n<h2><span style=\"font-weight: 400\">O Couchbase \u00e9 um banco de dados NoSQL<\/span><\/h2>\n<p><span style=\"font-weight: 400\">O Couchbase Server \u00e9 um banco de dados de documentos sem esquema, categorizado como um armazenamento de dados NoSQL, mas essa n\u00e3o \u00e9 a melhor descri\u00e7\u00e3o, pois o Couchbase usa uma variante do SQL para fazer consultas, chamada <a href=\"https:\/\/docs.couchbase.com\/server\/current\/getting-started\/try-a-query.html\">N1QL<\/a>. O fato de um esquema n\u00e3o ser rigorosamente aplicado em bancos de dados NoSQL como o Couchbase n\u00e3o significa que voc\u00ea n\u00e3o deva aplic\u00e1-lo.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Com o Couchbase, voc\u00ea obt\u00e9m os benef\u00edcios do dimensionamento de n\u00edvel empresarial, n\u00f3s em cluster e a capacidade de armazenar e recuperar dados em um formato JSON.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Se voc\u00ea estiver familiarizado com o Mongoose, um ODM para MongoDB, voc\u00ea se sentir\u00e1 bastante confort\u00e1vel com o Ottoman, pois eles t\u00eam muitos recursos que se sobrep\u00f5em, j\u00e1 que ambos s\u00e3o feitos para NodeJS e usados para modelar e persistir dados em um banco de dados de valores-chave orientado a documentos JSON.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Documento vs. Relacional <\/span><span style=\"font-weight: 400\">Banco de dados<\/span><\/h2>\n<p><span style=\"font-weight: 400\">Ao explorarmos o Couchbase e o banco de dados NoSQL e o design de esquema, primeiro veremos como uma estrutura de dados de documento difere do design de um banco de dados relacional. No exemplo abaixo, voc\u00ea ver\u00e1 uma compara\u00e7\u00e3o lado a lado dos dados que representam um hotel. <\/span><\/p>\n<p><span style=\"font-weight: 400\">\u00c0 esquerda, temos um documento que pode armazenar n\u00fameros de telefone em uma matriz, o que nos permite armazenar v\u00e1rios n\u00fameros de telefone de um \u00fanico hotel. Para fazer isso em um banco de dados relacional, voc\u00ea certamente precisaria de uma nova tabela e manter um relacionamento entre as duas usando chaves prim\u00e1rias.<\/span><\/p>\n<p><span style=\"font-weight: 400;font-size: 12px\"><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/03\/Hotel_PhoneNumbers.gif\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-10952\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/03\/Hotel_PhoneNumbers.gif\" alt=\"NoSQL Documents vs. Relational Tables in SQL\" width=\"1371\" height=\"573\" \/><\/a><\/span><\/p>\n<p style=\"text-align: center\"><span style=\"font-size: 14px;font-weight: 400\">Para obter mais informa\u00e7\u00f5es sobre modelagem de documentos, confira os recursos que reuni em uma postagem do blog: <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/a-json-data-modeling-guide\/\">Guia de modelagem de dados JSON<\/a><\/span><\/p>\n<p><span style=\"font-weight: 400\">No Ottoman, temos muitas constru\u00e7\u00f5es para ajudar a definir o esquema e os modelos no n\u00edvel do aplicativo. Vamos examinar alguns dos termos mais importantes que voc\u00ea precisa conhecer no Ottoman.<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Tipos<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Como visto em rosa na imagem acima, as propriedades do documento com o tipo de nome no Couchbase s\u00e3o quase equivalentes \u00e0s tabelas em um banco de dados relacional. Elas podem ajudar a agrupar diferentes tipos de documentos JSON para fins de indexa\u00e7\u00e3o. Ao usar \u00edndices secund\u00e1rios no Couchbase, podemos indexar em qualquer chave nos documentos. Se apenas 100 dos 10.000 documentos do seu banco de dados usarem um tipo de \"hotel\" e voc\u00ea normalmente quiser pesquisar hot\u00e9is com base na cidade ou no estado, conv\u00e9m criar um \u00cdndice Secund\u00e1rio Composto que s\u00f3 precise pesquisar os cem documentos em que a cidade ou o estado seja igual a um determinado valor. Isso \u00e9 muito mais eficiente do que usar, por exemplo, um \u00edndice prim\u00e1rio. <\/span><\/p>\n<p><span style=\"font-weight: 400\"><a href=\"https:\/\/docs.couchbase.com\/server\/current\/learn\/services-and-indexes\/indexes\/indexing-and-query-perf.html\">Saiba mais sobre a indexa\u00e7\u00e3o no Couchbase<\/a>!<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Cole\u00e7\u00f5es<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Semelhante aos tipos no Couchbase 6.x (vers\u00e3o principal mais recente do Couchbase no momento em que este artigo foi escrito) e n\u00e3o mostrado na ilustra\u00e7\u00e3o acima, as cole\u00e7\u00f5es ser\u00e3o favorecidas no Couchbase 7 (<\/span><a href=\"https:\/\/www.couchbase.com\/blog\/pt\/downloads\/\"><span style=\"font-weight: 400\">j\u00e1 em vers\u00e3o beta<\/span><\/a><span style=\"font-weight: 400\">). No caso de usar cole\u00e7\u00f5es, voc\u00ea simplesmente n\u00e3o teria um <strong>'tipo'<\/strong> em cada documento e, em vez disso, ter o documento atribu\u00eddo a uma propriedade <strong>'hotel'<\/strong> cole\u00e7\u00e3o.<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Documentos<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Compar\u00e1vel a linhas de dados em um banco de dados relacional. Os sistemas RDBMS tradicionais fazem refer\u00eancia a documentos relacionados de outras tabelas, como visto na ilustra\u00e7\u00e3o acima. No entanto, tamb\u00e9m \u00e9 poss\u00edvel fazer isso com um documento JSON; sugere-se incluir essas informa\u00e7\u00f5es como um documento incorporado quando poss\u00edvel, como vemos na propriedade de n\u00famero de telefone do documento do hotel, que \u00e9 uma matriz de n\u00fameros de telefone. Embora seja um exemplo muito simples, pense que se voc\u00ea tivesse uma propriedade de endere\u00e7o que fosse outro objeto JSON com muitas propriedades, voc\u00ea poderia pensar que ela precisaria ter seu pr\u00f3prio documento, mas aninhar essas informa\u00e7\u00f5es no documento pai, na maioria dos casos, n\u00e3o tem problema.<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Campos<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Tamb\u00e9m conhecidos como atributos, s\u00e3o semelhantes \u00e0s colunas em um banco de dados relacional e, com o Ottoman, voc\u00ea pode criar requisitos em n\u00edvel de campo como parte do seu esquema.<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Esquema<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Embora o Couchbase n\u00e3o tenha esquema ou seja flex\u00edvel, ainda podemos impor a estrutura no n\u00edvel do aplicativo para nossos documentos.<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Modelo<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Um m\u00e9todo construtor que recebe um esquema e cria uma inst\u00e2ncia de um documento equivalente a um \u00fanico registro em um banco de dados relacional. Essa inst\u00e2ncia de documento pode ser constru\u00edda e depois persistida no Couchbase pelo Ottoman <a href=\"https:\/\/v2.ottomanjs.com\/guides\/model.html#constructing-documents\">usando o <code>salvar()<\/code> m\u00e9todo<\/a>.<\/span><\/p>\n<h2><span style=\"font-weight: 400\">Primeiros passos<\/span><\/h2>\n<p>Vamos come\u00e7ar a criar um aplicativo de demonstra\u00e7\u00e3o que podemos usar para nos familiarizarmos com o Ottoman como um mapeador de documentos de objetos.<\/p>\n<h3><span style=\"font-weight: 400\">Instala\u00e7\u00e3o do Couchbase<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Antes de come\u00e7armos, vamos configurar o Couchbase. <\/span><\/p>\n<p><span style=\"font-weight: 400\">Voc\u00ea pode escolher entre <\/span><b>uma das seguintes op\u00e7\u00f5es<\/b><span style=\"font-weight: 400\"> (estamos usando a op\u00e7\u00e3o #1 para este artigo):<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/developer.couchbase.com\/docker-image-manual-cb65\/\"><span style=\"font-weight: 400\">Instalar o Couchbase Server usando o Docker<\/span><\/a><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Fa\u00e7a o download do Couchbase espec\u00edfico para seu sistema operacional no site <\/span><a href=\"https:\/\/www.couchbase.com\/blog\/pt\/downloads\/\"><span style=\"font-weight: 400\">Site do Couchbase<\/span><\/a><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400\">Vamos navegar por alguns dos conceitos b\u00e1sicos do Ottoman implementando um modelo que representa os dados de um exemplo simplificado de companhia a\u00e9rea, mantendo a tradi\u00e7\u00e3o do conjunto de dados Travel-Sample do Couchbase.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Estou usando o Visual Studio Code, o NodeJS v12.14 e o NPM 6.14.8, portanto, voc\u00ea precisar\u00e1 ter o Node.js instalado em seu computador.<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Inicializando nosso projeto com o NPM<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Crie um diret\u00f3rio, inicialize nosso projeto, instale o Ottoman.js e abra-o no VS Code<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:sh decode:true\" title=\"Create directory, initialize project, install Ottoman &amp; open in VS Code\">mkdir intro-ottoman &amp;&amp; cd $_ &amp;&amp; npm init -y &amp;&amp; npm i ottoman &amp;&amp; touch createAirline.js &amp;&amp; code .<\/pre>\n<p><span style=\"font-weight: 400\">Abra o terminal no editor de sua prefer\u00eancia. Eu adicionei um comando no final que abrir\u00e1 no VS Code.<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Conex\u00e3o com o Couchbase com o Ottoman<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Come\u00e7aremos a trabalhar a partir do arquivo <code>.\/createAirline.js<\/code><\/span> <span style=\"font-weight: 400\">na raiz do projeto e adicione o seguinte (com base na configura\u00e7\u00e3o padr\u00e3o):<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:javascript decode:true\" title=\"Conex\u00e3o com o Couchbase no Ottoman\">const { Ottoman, model, Schema } = require('ottoman')\r\n\r\nconst ottoman = new Ottoman({collectionName: '_default'});\r\nottoman.connect({\r\n    connectionString: 'couchbase:\/\/localhost',\r\n    bucketName: 'travel',\r\n    username: 'Administrator',\r\n    password: 'password'\r\n});<\/pre>\n<p><span style=\"font-weight: 400\">Juntos, eles importam o pacote ottoman e especificam a cole\u00e7\u00e3o padr\u00e3o (estilo do Couchbase Server 6.x)<\/span><\/p>\n<h3>Esquema e modelos otomanos<\/h3>\n<p><span style=\"font-weight: 400\">Os modelos s\u00e3o construtores sofisticados compilados a partir de defini\u00e7\u00f5es de esquema. Uma inst\u00e2ncia de um modelo \u00e9 chamada de documento. Os modelos no Ottoman ajudam voc\u00ea a criar, ler, atualizar e excluir facilmente documentos no banco de dados do Couchbase.<\/span><\/p>\n<p><span style=\"font-weight: 400\">A cria\u00e7\u00e3o de um modelo de otomana inclui alguns aspectos:<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Defini\u00e7\u00e3o de um esquema de documento<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Um esquema define as propriedades do documento por meio de um objeto em que o nome da chave corresponde ao nome da propriedade na cole\u00e7\u00e3o.<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:javascript decode:true\" title=\"Criar um esquema de companhia a\u00e9rea\">const airlineSchema = new Schema({\r\n   callsign: String, \r\n   country: String, \r\n   name: String \r\n})<\/pre>\n<p><span style=\"font-weight: 400\">Aqui definimos tr\u00eas propriedades <strong>(indicativo, pa\u00eds, nome)<\/strong> em nosso esquema, todos do tipo <\/span><b>Cordas.<\/b> Especificando um tipo para cada uma das propriedades do nosso modelo, <span style=\"font-weight: 400\">\u00a0mapeia para um validador interno que ser\u00e1 acionado quando o modelo for salvo no banco de dados e falhar\u00e1 se o tipo de dados do valor n\u00e3o for do tipo <\/span><b>Cordas<\/b><span style=\"font-weight: 400\">.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Os seguintes tipos de esquema s\u00e3o permitidos:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/v2.ottomanjs.com\/classes\/schema.html#string\"><span style=\"font-weight: 400\">Cordas<\/span><\/a><\/li>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/v2.ottomanjs.com\/classes\/schema.html#number\"><span style=\"font-weight: 400\">N\u00famero<\/span><\/a><\/li>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/v2.ottomanjs.com\/classes\/schema.html#array\"><span style=\"font-weight: 400\">Matriz<\/span><\/a><span style=\"font-weight: 400\">\u00a0<\/span><\/li>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/v2.ottomanjs.com\/classes\/schema.html#boolean\"><span style=\"font-weight: 400\">Booleano<\/span><\/a><\/li>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/v2.ottomanjs.com\/classes\/schema.html#date\"><span style=\"font-weight: 400\">Data<\/span><\/a><\/li>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/v2.ottomanjs.com\/classes\/embedtype.html\"><span style=\"font-weight: 400\">EmbedType<\/span><\/a><\/li>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/v2.ottomanjs.com\/classes\/mixedtype.html\"><span style=\"font-weight: 400\">MixedType<\/span><\/a><\/li>\n<li style=\"font-weight: 400\"><a href=\"https:\/\/v2.ottomanjs.com\/classes\/referencetype.html\"><span style=\"font-weight: 400\">ReferenceTypes<\/span><\/a><\/li>\n<\/ul>\n<h3><span style=\"font-weight: 400\">Defini\u00e7\u00e3o de um modelo de documento<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Precisamos chamar o construtor do modelo na inst\u00e2ncia do ottoman e passar a ele o nome da cole\u00e7\u00e3o e uma refer\u00eancia \u00e0 defini\u00e7\u00e3o do esquema.<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:javascript decode:true\" title=\"Criar modelo de companhia a\u00e9rea\">const Airline = ottoman.model('Airline', airlineSchema)<\/pre>\n<p><span style=\"font-weight: 400\">Quando voc\u00ea chama o <\/span><a href=\"https:\/\/v2.ottomanjs.com\/classes\/ottoman.html#model\"><span style=\"font-weight: 400\">modelo()<\/span><\/a><span style=\"font-weight: 400\"> ela cria uma c\u00f3pia do esquema e compila o modelo para voc\u00ea.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Vamos tamb\u00e9m dar o <\/span><code>airlineSchema<\/code><span style=\"font-weight: 400\"> uma propriedade de n\u00famero de telefone. Podemos adicionar uma fun\u00e7\u00e3o de valida\u00e7\u00e3o que garantir\u00e1 que o valor seja um n\u00famero de telefone v\u00e1lido. Substitua a fun\u00e7\u00e3o <code>airlineSchema<\/code> com esses tr\u00eas blocos de c\u00f3digo:<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:javascript decode:true\" title=\"Adicionar validador ao esquema da companhia a\u00e9rea\">const regx = \/^(\\([0-9]{3}\\)|[0-9]{3}-)[0-9]{3}-[0-9]{4}$\/\r\n  if(value &amp;&amp; !value.match(regx)) {\r\n    throw new Error(`Phone Number ${value} is not valid`)\r\n  }\r\n}\r\naddValidators({ \r\n  phone: phoneValidator\r\n})\r\nconst airlineSchema = new Schema({ \r\n  callsign: String, \r\n  country: String, \r\n  name: String,\r\n  phone: [{ type: String, validator: 'phone'}]\r\n})<\/pre>\n<p><span style=\"font-weight: 400\">No exemplo acima, mostrei como criar um validador personalizado. Acontece que estamos usando uma express\u00e3o regular como check-in do nosso validador. Entenda que voc\u00ea pode ter qualquer l\u00f3gica dentro de um desses validadores e, daqui a pouco, mostrarei um bom truque para reduzir nosso c\u00f3digo, considerando que estamos usando uma express\u00e3o regular para a correspond\u00eancia dos n\u00fameros de telefone.<\/span><\/p>\n<h4>Defini\u00e7\u00e3o de validadores<\/h4>\n<p><strong>Validadores<\/strong> registrado com Ottoman (como fizemos aqui com o <code class=\"language-JavaScript\">ottoman.addValidators()<\/code> ) ser\u00e1 chamado uma vez para cada valor que a propriedade do nosso documento tiver na matriz. Se a propriedade n\u00e3o tivesse uma matriz e, em vez disso, tivesse apenas um \u00fanico valor String, o validador seria executado apenas uma vez. Por esse motivo, imprimo o n\u00famero de telefone problem\u00e1tico se a valida\u00e7\u00e3o falhar.<\/p>\n<p><span style=\"font-weight: 400\">No entanto, h\u00e1 uma maneira mais f\u00e1cil de validar qualquer valor de propriedades do documento, desde que a verifica\u00e7\u00e3o que voc\u00ea est\u00e1 realizando use uma express\u00e3o regular. A express\u00e3o <a href=\"https:\/\/v2.ottomanjs.com\/interfaces\/validatoroption.html#hierarchy'\">ValidatorOption<\/a> pode tomar um <strong>regexp<\/strong> e <strong>mensagem <\/strong>como um argumento, para que possamos reduzir nosso c\u00f3digo para:<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:javascript decode:true\" title=\"Esquema Udate para usar o validador\">const regx = \/^(\\([0-9]{3}\\)|[0-9]{3}-)[0-9]{3}-[0-9]{4}$\/\r\nconst airlineSchema = new Schema({\r\ncallsign: String,\r\ncountry: String,\r\nname: String,\r\nphone: [{type: String, validator: {regexp: regx, message: 'phone invalid'}}]\r\n})<\/pre>\n<p><span style=\"font-weight: 400\">Como voc\u00ea pode ver, podemos fazer tudo o que est\u00e1vamos fazendo antes em linha ao criar um novo esquema. Mas n\u00e3o deixe que isso o impe\u00e7a de entender como criar um validador personalizado. \u00c0s vezes, precisamos de l\u00f3gica adicional e \u00e9 por isso que o primeiro exemplo ainda \u00e9 algo que vale a pena conhecer.<\/span><\/p>\n<h3><b>B\u00e1sico <\/b><b>Opera\u00e7\u00f5es de documentos em NoSQL<\/b><\/h3>\n<p><span style=\"font-weight: 400\">A maioria das opera\u00e7\u00f5es b\u00e1sicas \u00e9 abordada em nossa documenta\u00e7\u00e3o do Ottoman V2. Abordaremos algumas delas aqui, mas sinta-se \u00e0 vontade para mergulhar em nossa <a href=\"https:\/\/v2.ottomanjs.com\">Documentos do Ottoman V2 (alfa)<\/a> e nos informe se houver algo que voc\u00ea n\u00e3o consiga encontrar ou n\u00e3o entenda.<\/span><\/p>\n<h4><b>Criar documentos<\/b><\/h4>\n<p><span style=\"font-weight: 400\">Considerando o c\u00f3digo que j\u00e1 examinamos acima, que cria um esquema, um modelo e validadores. Salvar um modelo e persisti-lo no banco de dados \u00e9 muito f\u00e1cil. Vamos criar um novo <code>Companhia a\u00e9rea<\/code> usando nosso modelo <code>Esquema<\/code> e, em seguida, salv\u00e1-lo\/persisti-lo no banco de dados.<\/span><span style=\"font-weight: 400\"><br \/>\n<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:javascript decode:true\" title=\"Create Document &amp; Save to Couchbase\">\/\/ Constructing our document\r\nconst cbAirlines = new Airline({\r\n  callsign: 'CBA',\r\n  country: 'United States',\r\n  name: 'Couchbase Airlines',\r\n  phone: ['321-321-3210', '321-123-1234']\r\n})\r\n\r\n\/\/ Persist the Couchbase Airlines document to Couchbase Server\r\nconst saveDocument = async() =&gt; {\r\n  try {\r\n    const result = await cbAirlines.save()\r\n    console.log(result)\r\n  } catch (error) {\r\n    throw error\r\n  }\r\n}\r\n\r\n\/\/ Ensure that all indexes exist on the server\r\nottoman.start()\r\n  \/\/ Next, let's save our document and print a success message \r\n  .then(async() =&gt; {\r\n    saveDocument()\r\n      .then(() =&gt; process.exit(0))\r\n      .catch((error) =&gt; console.log(error))\r\n  })<\/pre>\n<p>Voc\u00ea pode estar se perguntando por que n\u00e3o chamamos apenas o <code>saveDocument()<\/code> por si s\u00f3. Em vez disso, n\u00f3s a chamamos ap\u00f3s a fun\u00e7\u00e3o <code>ottoman.start()<\/code> est\u00e1 conclu\u00edda. O <code>iniciar<\/code> \u00e9 um atalho para executar o m\u00e9todo\u00a0<code>ensureCollections<\/code>\u00a0e\u00a0<code>ensureIndexes<\/code>. Tudo o que voc\u00ea precisa saber por enquanto \u00e9 que esse m\u00e9todo garante que os \u00edndices apropriados relacionados ao Ottoman tenham sido criados no Couchbase, e isso \u00e9 importante para garantir que possamos executar coisas como o <code>find()<\/code> e usar ferramentas como o m\u00e9todo <code>Criador de consultas<\/code> que ser\u00e1 abordado no final do artigo.<\/p>\n<p><span style=\"font-weight: 400\">Neste ponto, se voc\u00ea executasse todo o c\u00f3digo que escrevemos usando o Node, nosso documento seria salvo no banco de dados:<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:sh decode:true\" title=\"Executar o createAirline com o Node\">n\u00f3 createAirline.js<\/pre>\n<p><span style=\"font-weight: 400\">O resultado dessa opera\u00e7\u00e3o:<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:sh decode:true\" title=\"Resultado de Save Airline\">_Model {\r\n  callsign: 'CBA',\r\n  country: 'United States',\r\n  name: 'Couchbase Airlines',\r\n  phone: [ '321-321-3210', '321-123-1234' ],\r\n  id: '2384568f-f1e9-446e-97d1-cad697c40e76',\r\n  _type: 'Airline'\r\n}<\/pre>\n<p><span style=\"font-weight: 400\">Os seguintes campos s\u00e3o retornados:<\/span><\/p>\n<ol>\n<li>Os campos de indicativo, pa\u00eds e nome s\u00e3o todos String, o valor mais b\u00e1sico que podemos ter em um documento.<\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\"><span style=\"font-weight: 400\"><span style=\"font-weight: 400\">O campo id \u00e9 gerado automaticamente pelo Couchbase e \u00e9 uma chave exclusiva. O valor do ID \u00e9 o que voc\u00ea usar\u00e1 em qualquer caso para encontrar um documento com o Ottoman em m\u00e9todos como <code>findByID<\/code> ou <code>removeByID<\/code><\/span><\/span><\/span><\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">O campo telefone \u00e9 representado por uma matriz e cont\u00e9m n\u00fameros de telefone v\u00e1lidos.<\/span><\/li>\n<li>O <span style=\"font-weight: 400\">O campo _type pode nos ajudar a organizar nossos documentos como uma tabela faz em um banco de dados relacional, <\/span><a href=\"https:\/\/docs.couchbase.com\/server\/7.0\/learn\/data\/scopes-and-collections.html\"><span style=\"font-weight: 400\">No Couchbase 7, podemos usar cole\u00e7\u00f5es e escopos<\/span><\/a><span style=\"font-weight: 400\">.<\/span><\/li>\n<\/ol>\n<h5><span style=\"font-weight: 400\">Erros de valida\u00e7\u00e3o<\/span><\/h5>\n<p><span style=\"font-weight: 400\">Se inserirmos um n\u00famero de telefone inv\u00e1lido e executarmos <code>n\u00f3 createAirline.js<\/code> esse arquivo novamente, receber\u00edamos uma mensagem de erro:<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:sh decode:true\" title=\"Resultado do erro de valida\u00e7\u00e3o\">ValidationError: Phone Number 321-321-32xx is not valid<\/pre>\n<p>DICA: voc\u00ea pode definir sua conex\u00e3o, esquema e modelos em arquivos separados, export\u00e1-los e us\u00e1-los em outros arquivos. Crie um novo arquivo chamado <code>modelo de esquema de companhia a\u00e9rea.js<\/code> e mover nosso esquema e defini\u00e7\u00e3o de modelo para ele:<\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:javascript decode:true\" title=\"Esquema e modelo de exporta\u00e7\u00e3o\">const { model, Schema } = require('ottoman')\r\n\r\nconst regx = \/^(\\([0-9]{3}\\)|[0-9]{3}-)[0-9]{3}-[0-9]{4}$\/\r\nconst airlineSchema = new Schema({ \r\n  callsign: String, \r\n  country: String, \r\n  name: String,\r\n  phone: [{type: String, validator: {regexp: regx, message: 'phone invalid'}}]\r\n})\r\n\r\n\/\/ Compile our model using our schema\r\nconst Airline = model('Airline', airlineSchema)\r\n\r\nexports.airlineSchema = airlineSchema;\r\nexports.Airline = Airline;<\/pre>\n<p>Agora podemos criar alguns arquivos novos, <code>findAirline.js<\/code>, <code>updateAirline.js<\/code>e <code>removeAirline.js<\/code> e preencha cada arquivo com o seguinte:<\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:javascript decode:true\" title=\"Boilerplate para v\u00e1rios arquivos\">const { Ottoman } = require('ottoman')\r\nconst ottoman = new Ottoman({collectionName: '_default'});\r\nottoman.connect({\r\n    connectionString: 'couchbase:\/\/localhost',\r\n    bucketName: 'travel',\r\n    username: 'Administrator',\r\n    password: 'password'\r\n});\r\n\r\nconst { Airline } = require('.\/airline-schema-and-model')<\/pre>\n<p><span style=\"font-weight: 400\">Isso nos ajudar\u00e1 a separar parte do nosso c\u00f3digo para que n\u00e3o o repitamos em cada arquivo e, \u00e0 medida que analisarmos cada uma das opera\u00e7\u00f5es CRUD, poderemos simplesmente adicionar algum c\u00f3digo a cada arquivo, e nosso esquema e modelo j\u00e1 ser\u00e3o importados.<\/span><\/p>\n<h4><span style=\"font-weight: 400\">Localizar documentos<\/span><\/h4>\n<p><span style=\"font-weight: 400\">Vamos tentar recuperar o registro que salvamos no banco de dados anteriormente. A classe de modelo exp\u00f5e v\u00e1rios m\u00e9todos est\u00e1ticos e de inst\u00e2ncia para executar opera\u00e7\u00f5es no banco de dados. Agora tentaremos encontrar o registro que criamos anteriormente usando o m\u00e9todo find e passando o indicativo como termo de pesquisa. Vamos criar um novo arquivo chamado <code>findAirline.js<\/code> e podemos adicionar o seguinte c\u00f3digo:<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:javascript decode:true\" title=\"Localizar documento de companhia a\u00e9rea por indicativo\">\/\/ Find the Couchbase Airline document by Callsign from Couchbase Server\r\nconst findDocument = async() =&gt; {\r\n  try {\r\n    Airline.find({ callsign: { $like: 'CBA' } })\r\n    .then((result) =&gt; console.log(result.rows));\r\n  } catch (error) {\r\n    throw error\r\n  }\r\n}\r\n\r\nottoman.start()\r\n  .then(async() =&gt; {\r\n    findDocument()\r\n      .then(() =&gt; process.exit(0))\r\n      .catch((error) =&gt; console.log(error))\r\n  })<\/pre>\n<p><span style=\"font-weight: 400\">Localizar resultado do documento:<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:sh decode:true\" title=\"Resultado de Localizar companhia a\u00e9rea por indicativo\">Query Result:  [\r\n  _Model {\r\n    _type: 'Airline',\r\n    callsign: 'CBA',\r\n    country: 'United States',\r\n    name: 'Couchbase Airlines',\r\n    phone: ['321-321-3210','321-123-1234'],\r\n    id: '971045ac-39d8-4e72-8c93-fdaac69aae31',\r\n  }<\/pre>\n<h4><span style=\"font-weight: 400\">Atualizar documentos<\/span><\/h4>\n<p><span style=\"font-weight: 400\">Vamos modificar o registro acima, encontrando-o usando o indicativo de chamada, que podemos presumir que ser\u00e1 um campo exclusivo em nossos dados, e ent\u00e3o poderemos atualizar o documento em uma \u00fanica opera\u00e7\u00e3o.<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:javascript decode:true\" title=\"Localizar documento da companhia a\u00e9rea e atualizar\">\/\/ Update the Couchbase Airline document by Callsign from Couchbase Server\r\nconst findDocumentAndUpdate = async() =&gt; {\r\n  const newDocument = {\r\n    callsign: 'CBSA',\r\n    country: 'United States',\r\n    name: 'Couchbase Airways',\r\n    phone: ['321-321-3210','321-123-1234']\r\n  }\r\n  try {\r\n    let result = await Airline.findOneAndUpdate(\r\n      { callsign: { $like: 'CBA' } }, newDocument, { new: true }\r\n    )\r\n    console.log(result)\r\n  } catch (error) {\r\n    throw error\r\n  }\r\n}\r\n\r\nottoman.start()\r\n  .then(async() =&gt; {\r\n    findDocumentAndUpdate()\r\n      .then(() =&gt; process.exit(0))\r\n      .catch((error) =&gt; console.log(error))\r\n  })<\/pre>\n<p><span style=\"font-weight: 400\">Localize o documento e atualize o resultado:<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:sh decode:true\" title=\"Resultado da atualiza\u00e7\u00e3o e do documento Find Airline\">_Model {\r\n  _type: 'Airline',\r\n  callsign: 'CBSA',\r\n  country: 'United States',\r\n  id: '971045ac-39d8-4e72-8c93-fdaac69aae31',\r\n  name: 'Couchbase Airways',\r\n  phone: [ '321-321-3210', '321-123-1234' ]\r\n}<\/pre>\n<h4><span style=\"font-weight: 400\">Remover documentos<\/span><\/h4>\n<p><span style=\"font-weight: 400\">O Ottoman tem v\u00e1rios m\u00e9todos que lidam com a remo\u00e7\u00e3o de documentos: <\/span><a href=\"https:\/\/v2.ottomanjs.com\/classes\/document.html#remove\"><span style=\"font-weight: 400\">remover<\/span><\/a><span style=\"font-weight: 400\">, <\/span><a href=\"https:\/\/v2.ottomanjs.com\/classes\/model.html#static-removebyid\"><span style=\"font-weight: 400\">removeById<\/span><\/a><span style=\"font-weight: 400\"> e <\/span><a href=\"https:\/\/v2.ottomanjs.com\/classes\/model.html#static-removemany\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400\">removeMany<\/span><\/a><span style=\"font-weight: 400\">. Considerando os muitos exemplos que tivemos at\u00e9 agora, cada um deles deve ser muito f\u00e1cil de entender como usar, portanto, forneceremos apenas um exemplo simples aqui para mostrar como remover um documento que j\u00e1 encontramos usando o <strong>find()<\/strong> m\u00e9todo.<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:javascript decode:true\" title=\"Remover documento da companhia a\u00e9rea por identifica\u00e7\u00e3o\">\/\/ Remove the Couchbase Airline document by ID from Couchbase Server\r\nconst removeDocument = async() =&gt; {\r\n  try {\r\n    await Airline.removeById('60e3f517-6a2a-41fe-be45-97081181d675')\r\n      .then((result) =&gt; console.log(result))\r\n  } catch (error) {\r\n    throw error\r\n  }\r\n}<\/pre>\n<p><span style=\"font-weight: 400\">O resultado da remo\u00e7\u00e3o do documento \u00e9 um simples <a href=\"https:\/\/docs.couchbase.com\/nodejs-sdk\/current\/howtos\/concurrent-document-mutations.html\" target=\"_blank\" rel=\"noopener\">valor do cas<\/a>usado para rastrear altera\u00e7\u00f5es nos documentos do Couchbase.<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:sh decode:true\" title=\"Resultado de Remove Airline Document by Id\">{ cas: CbCas { '0': &lt;Buffer 00 00 2e 30 62 db 6c 16&gt; } }<\/pre>\n<h3><span style=\"font-weight: 400\">Middleware<\/span><\/h3>\n<p><span style=\"font-weight: 400\">J\u00e1 vimos nosso middleware em a\u00e7\u00e3o, nosso validador que criamos inicialmente pode aproveitar o middleware usando fun\u00e7\u00f5es que s\u00e3o executadas em est\u00e1gios espec\u00edficos de um pipeline, passando o controle durante a execu\u00e7\u00e3o de fun\u00e7\u00f5es ass\u00edncronas.<\/span><\/p>\n<h4 id=\"the-available-hooks-are\">Ganchos dispon\u00edveis<\/h4>\n<ul>\n<li><code>validar<\/code><\/li>\n<li><code>salvar<\/code><\/li>\n<li><code>atualiza\u00e7\u00e3o<\/code><\/li>\n<li><code>remover<\/code><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400\">Exemplo de middleware (tamb\u00e9m conhecido como <a href=\"https:\/\/v2.ottomanjs.com\/guides\/schema.html#instance-methods\" target=\"_blank\" rel=\"noopener\">pr\u00e9 e p\u00f3s-ganchos<\/a>)<\/span><\/p>\n<p><span style=\"font-weight: 400\">Vamos tentar um exemplo simplesmente gerando um registro no console antes e depois da cria\u00e7\u00e3o (salvamento) de um documento. Vou criar um novo arquivo chamado createWithHooks.js e a maior parte do c\u00f3digo parecer\u00e1 familiar, exceto pelo fato de eu ter adicionado ganchos pr\u00e9 e p\u00f3s que apenas nos informar\u00e3o o nome do documento antes do salvamento e o ID do documento depois do salvamento:<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:javascript decode:true\" title=\"Criar documento com ganchos pr\u00e9\/p\u00f3s-salvamento\">const { Ottoman } = require('ottoman')\r\nconst ottoman = new Ottoman({collectionName: '_default'});\r\nottoman.connect({\r\n    connectionString: 'couchbase:\/\/localhost',\r\n    bucketName: 'travel',\r\n    username: 'Administrator',\r\n    password: 'password'\r\n});\r\n\r\nconst { Airline, airlineSchema } = require('.\/airline-schema-and-model')\r\n\r\n\/\/ Plugins and Hooks are middleware, think lifecycle hooks!\r\nconst pluginLog = (airlineSchema) =&gt; {\r\n  airlineSchema.pre('save', (doc) =&gt; \r\n    console.log(`Doc: ${doc.name} about to be saved`)\r\n  )\r\n  airlineSchema.post('save', (doc) =&gt; \r\n    console.log(`Doc: ${doc.id} has been saved`)\r\n  )\r\n};\r\n\r\n\/\/ Our plugin must be registered before the model creation\r\nairlineSchema.plugin(pluginLog)\r\n\r\n\/\/ Constructing our document\r\nconst cbAirlines = new Airline({\r\n  callsign: 'UNITED',\r\n  country: 'United States',\r\n  name: 'United Airlines',\r\n  phone: ['321-321-3210', '321-123-1234']\r\n})\r\n\r\nconst saveDocument = async() =&gt; {\r\n  try {\r\n    \/\/ pre and post hooks will run\r\n    const result = await cbAirlines.save()\r\n    console.log(result)\r\n  } catch (error) {\r\n    throw error\r\n  }\r\n}\r\n\r\nottoman.start()\r\n  .then(async() =&gt; {\r\n    saveDocument()\r\n      .then(() =&gt; process.exit(0))\r\n      .catch((error) =&gt; console.log(error))\r\n  })<\/pre>\n<p><span style=\"font-weight: 400\">Salvar o resultado do documento:<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:sh decode:true\" title=\"Resultado Salvar documento da companhia a\u00e9rea\">Doc: United Airlines about to be saved\r\nDoc: 1316488a-98ba-4dbb-b0d7-ea6001a0bf57 has been saved\r\n_Model {\r\n  callsign: 'UNITED',\r\n  country: 'United States',\r\n  name: 'United Airlines',\r\n  phone: [ '321-321-3210', '321-123-1234' ],\r\n  id: '1316488a-98ba-4dbb-b0d7-ea6001a0bf57',\r\n  _type: 'Airline'\r\n}<\/pre>\n<p><span style=\"font-weight: 400\">Recebemos nossas mensagens antes e depois do salvamento. Com a valida\u00e7\u00e3o, voc\u00ea pode garantir que determinados valores de propriedade do documento atendam aos seus crit\u00e9rios. O acesso ao ciclo de vida quando o documento \u00e9 salvo, atualizado e removido tamb\u00e9m nos ajudou a ter um controle sobre o middleware Ottoman!\u00a0<\/span><\/p>\n<h3><span style=\"font-weight: 400\">Cria\u00e7\u00e3o de consultas<\/span><\/h3>\n<p><span style=\"font-weight: 400\">O Ottoman tem uma API muito rica que lida com muitas opera\u00e7\u00f5es complexas compat\u00edveis com o Couchbase e o N1QL. Nosso construtor de consultas nos bastidores cria suas instru\u00e7\u00f5es N1QL para voc\u00ea. Ao usar o Query Builder, voc\u00ea tem tr\u00eas op\u00e7\u00f5es de qual modo usar.\u00a0<\/span><\/p>\n<ol>\n<li><a href=\"https:\/\/v2.ottomanjs.com\/guides\/query-builder.html#build-a-query-by-using-parameters\" target=\"_blank\" rel=\"noopener\">Usando par\u00e2metros<\/a><\/li>\n<li><a href=\"https:\/\/v2.ottomanjs.com\/guides\/query-builder.html#build-a-query-by-using-access-functions\" target=\"_blank\" rel=\"noopener\">Fun\u00e7\u00f5es de acesso<\/a><\/li>\n<li><a href=\"https:\/\/v2.ottomanjs.com\/guides\/query-builder.html#build-a-query-by-using-parameters-and-function-parameters\" target=\"_blank\" rel=\"noopener\">ou usando Par\u00e2metros e Fun\u00e7\u00f5es de Acesso<\/a><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400\">Nos pr\u00f3ximos tr\u00eas exemplos, farei a mesma coisa usando cada um dos tr\u00eas modos diferentes do QueryBuilder (par\u00e2metros, fun\u00e7\u00f5es de acesso e modo misto). Cada exemplo ter\u00e1:<br \/>\n<\/span><\/p>\n<ol>\n<li><span style=\"font-weight: 400\">Selecione <code>nome<\/code> e <code>pa\u00eds<\/code> da Companhia A\u00e9rea<\/span><\/li>\n<li>Onde o <code>pa\u00eds<\/code> O valor \u00e9 \"United States\" (Estados Unidos)<\/li>\n<li>E LIMITAR nossos resultados a 10<\/li>\n<\/ol>\n<p>Vamos primeiro criar um novo arquivo chamado: <code>findWithQueryBuilder.js<\/code>e adicione o seguinte c\u00f3digo:<\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:javascript decode:true\" title=\"Localizar documentos de companhias a\u00e9reas com o QueryBuilder\">const { Ottoman, Query } = require('ottoman')\r\nconst ottoman = new Ottoman({collectionName: '_default'});\r\n\r\nottoman.connect({\r\n    connectionString: 'couchbase:\/\/localhost',\r\n    bucketName: 'travel',\r\n    username: 'Administrator',\r\n    password: 'password'\r\n});\r\n\r\n\/* Replace with QueryBuilder Example *\/\r\n\r\nconst executeQuery = async(query) =&gt; {\r\n  try {\r\n    const result = await ottoman.query(query)\r\n    console.log('Query Result: ' , result)\r\n  } catch (error) {\r\n    throw error\r\n  }\r\n}\r\n\r\ngenerateQuery()\r\n  .then((query) =&gt; {\r\n    executeQuery(query)\r\n      .then(() =&gt; process.exit(0))\r\n  })\r\n  .catch((error) =&gt; console.log(error))<\/pre>\n<p>Esse arquivo tem um coment\u00e1rio no meio que diz: <strong>\"Substituir por um exemplo de QueryBuilder\"<\/strong>. Podemos simplesmente copiar qualquer um dos exemplos a seguir nesta se\u00e7\u00e3o para essa \u00e1rea do arquivo.<\/p>\n<h4>Par\u00e2metros<\/h4>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:javascript decode:true\" title=\"Demonstrar o Query Builder usando par\u00e2metros\">const generateQuery = async() =&gt; {\r\n  try {\r\n    const params = {\r\n      select : [\r\n        { $field: 'name' }, \r\n        { $field: 'country'}\r\n      ],\r\n      where: { $and: [\r\n        { country: {$eq: 'United States'}},\r\n        { _type: {$eq: 'Airline'}}\r\n      ] },\r\n      limit: 10\r\n    }\r\n    const query = new Query(params, '`travel`').build()\r\n    console.log('Query Generated: ', query)\r\n    return query\r\n  } catch (error) {\r\n    throw error\r\n  }\r\n}<\/pre>\n<h4>Fun\u00e7\u00f5es de acesso<\/h4>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:javascript decode:true\" title=\"Demonstrar o Query Builder usando as fun\u00e7\u00f5es do Access\">const generateQuery = async() =&gt; {\r\n  try {\r\n    const query = new Query({}, '`travel`')\r\n      .select([\r\n        { $field: 'name' }, \r\n        { $field: 'country'}\r\n      ])\r\n      .where({ $and: [\r\n        { country: {$eq: 'United States'}},\r\n        { _type: {$eq: 'Airline'}}\r\n      ]})\r\n      .limit(10)\r\n      .build()\r\n      console.log('Query Generated: ', query)\r\n      return query\r\n  } catch (error) {\r\n    throw error\r\n  }\r\n}<\/pre>\n<h4>Modo misto<\/h4>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:javascript decode:true\" title=\"Demonstrate Query Builder using Mixed Mode (Parameters &amp; Access Functions)\">const generateQuery = async() =&gt; {\r\n  try {\r\n    const where =  { $and: [\r\n      { country: {$eq: 'United States'}},\r\n      { _type: {$eq: 'Airline'}}\r\n    ] }\r\n    \/\/ pass in our query as a condition expression\r\n    const query = new Query({ where }, '`travel`')\r\n      .select([\r\n        { $field: 'name' }, \r\n        { $field: 'country' }\r\n      ])\r\n      .limit(10)\r\n      .build()\r\n      console.log('Query Generated: ', query)\r\n      return query\r\n  } catch (error) {\r\n    throw error\r\n  }\r\n}<\/pre>\n<p><span style=\"font-weight: 400\">Uma vez que voc\u00ea tenha criado um <code>generateQuery()<\/code> usando um dos modos mistos acima, voc\u00ea precisaria chamar de forma ass\u00edncrona a fun\u00e7\u00e3o <code>generateQuery<\/code> e <code>executeQuery<\/code> e o c\u00f3digo para isso, como eu disse, funcionar\u00e1 com muitas variantes do c\u00f3digo acima:<\/span><\/p>\n<p><span style=\"font-weight: 400\">Um resultado de qualquer um dos tr\u00eas modos acima:<\/span><\/p>\n<pre class=\"theme:vs2012 font:ubuntu-mono font-size:14 line-height:24 top-margin:0 h-align:1 toolbar:1 toolbar-overlay:false lang:sh decode:true\" title=\"Resultado da localiza\u00e7\u00e3o do documento da companhia a\u00e9rea com o QueryBuilder\">Query Generated:  SELECT name,country FROM default:`travel` WHERE (country=\"United States\" AND _type=\"Airline\") LIMIT 10\r\nQuery Result:  {\r\n  meta: {\r\n    requestId: '1514fa20-755e-49b3-bbfa-4ed75a1a40ee',\r\n    clientContextId: '0334862c79e727f8',\r\n    status: 'success',\r\n    signature: { country: 'json', name: 'json' },\r\n    profile: undefined,\r\n    metrics: {\r\n      elapsedTime: 6.219,\r\n      executionTime: 5.9619,\r\n      sortCount: undefined,\r\n      resultCount: 2,\r\n      resultSize: 106,\r\n      mutationCount: undefined,\r\n      errorCount: undefined,\r\n      warningCount: undefined\r\n    }\r\n  },\r\n  rows: [\r\n    { country: 'United States', name: 'United Airlines' },\r\n    { country: 'United States', name: 'Jet Blue Airlines' }\r\n  ]\r\n}<\/pre>\n<h3><span style=\"font-weight: 400\">Recursos<\/span><\/h3>\n<ul>\n<li style=\"list-style-type: none\">\n<ul>\n<li><a href=\"https:\/\/github.com\/couchbaselabs\/node-ottoman\" target=\"_blank\" rel=\"noopener\">Reposit\u00f3rio GitHub para Ottoman<\/a><\/li>\n<li><a href=\"https:\/\/ottomanjs.com\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400\">Documenta\u00e7\u00e3o para o Otomano V2<\/span><\/a><\/li>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/ottoman\" target=\"_blank\" rel=\"noopener\">Pacote Ottoman no NPM<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/httpJunkie\/intro-to-ottoman-v2\" target=\"_blank\" rel=\"noopener\">Introdu\u00e7\u00e3o ao Ottoman com c\u00f3digo-fonte do Couchbase<\/a><\/li>\n<li><a href=\"https:\/\/www.couchbase.com\/blog\/pt\/a-json-data-modeling-guide\/\" target=\"_blank\" rel=\"noopener\">Um guia de modelagem de dados JSON<\/a><\/li>\n<li><a href=\"https:\/\/www.youtube.com\/watch?v=0FIVaXCh2E8\" target=\"_blank\" rel=\"noopener\">Uma experi\u00eancia melhor para o desenvolvedor com o OttomanJS<\/a><\/li>\n<li><a href=\"https:\/\/docs.couchbase.com\/nodejs-sdk\/current\/hello-world\/start-using-sdk.html\" target=\"_blank\" rel=\"noopener\">SDK do Couchbase NodeJS<\/a><\/li>\n<li><a href=\"https:\/\/hub.docker.com\/_\/couchbase\" target=\"_blank\" rel=\"noopener\">Imagens oficiais do Docker do Couchbase<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3><span style=\"font-weight: 400\">Conclus\u00e3o<\/span><\/h3>\n<p><span style=\"font-weight: 400\">Fizemos um tour guiado pelo Ottoman, adquirindo uma compreens\u00e3o de muitos conceitos. Esquema, modelos, middleware, plug-ins, hooks e cria\u00e7\u00e3o de consultas.<\/span><\/p>\n<p><span style=\"font-weight: 400\">Exploramos como se conectar ao Couchbase no Ottoman. Definimos esquemas e modelos. Abordamos v\u00e1rios fundamentos do esquema e do design do banco de dados NoSQL. Por fim, examinamos algumas das opera\u00e7\u00f5es CRUD mais \u00fateis. Tudo para que voc\u00ea possa criar, ler, atualizar e excluir documentos no Couchbase via Ottoman.<\/span><\/p>\n<h4>D\u00ea feedback e contribua<\/h4>\n<p>Espero que este artigo tenha desmistificado por que e como usar o Ottoman e o ODM para o Couchbase. Conforme demonstrado, voc\u00ea pode usar o Ottoman para projetar o esquema do banco de dados NoSQL, validar e reduzir o padr\u00e3o. A escrita de opera\u00e7\u00f5es CRUD \u00e9 simplificada e ajuda no desenvolvimento r\u00e1pido.<\/p>\n<p>Se voc\u00ea tiver alguma d\u00favida sobre o Ottoman, quiser ajudar a contribuir com esse projeto de c\u00f3digo aberto ou apenas quiser dizer ol\u00e1, meu nome \u00e9 Eric Bishard e sou o Developer Advocate aqui na Couchbase, com foco na experi\u00eancia do desenvolvedor de Node.js e JavaScript. <a href=\"https:\/\/twitter.com\/httpjunkie\">Twitter\/@httpJunkie<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Ottoman is an Object Data Modeler (ODM) for Couchbase&#8217;s Node.js SDK providing JSON schema and validation for NoSQL. Why Use an ODM for Couchbase With Ottoman, you declare schema in your code. Although Couchbase has no schema enforcement for your [&hellip;]<\/p>","protected":false},"author":53002,"featured_media":11030,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1819,1822,10128,2201],"tags":[2312,1510],"ppma_author":[8922],"class_list":["post-10947","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-data-modeling","category-node-js","category-ottoman","category-tools-sdks","tag-document-database","tag-odm"],"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>Ottoman: Object Data Modeler (ODM) for Couchbase Node.js SDK<\/title>\n<meta name=\"description\" content=\"Ottoman is an Object Data Modeler (ODM) for Couchbase\u2019s Node.js SDK providing JSON schema and validation for NoSQL. Learn why to use an ODM for Couchbase.\" \/>\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\/introduction-to-ottoman-with-couchbase\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Introduction to Ottoman With Couchbase\" \/>\n<meta property=\"og:description\" content=\"Ottoman is an Object Data Modeler (ODM) for Couchbase\u2019s Node.js SDK providing JSON schema and validation for NoSQL. Learn why to use an ODM for Couchbase.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/introduction-to-ottoman-with-couchbase\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-03-30T16:13:45+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T06:42:25+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/feature-image-c.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"628\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Eric Bishard\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@httpJunkie\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Eric Bishard\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/\"},\"author\":{\"name\":\"Eric Bishard\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/67d3a4b597e42370ccd34b715a6b1f4c\"},\"headline\":\"Introduction to Ottoman With Couchbase\",\"datePublished\":\"2021-03-30T16:13:45+00:00\",\"dateModified\":\"2025-06-14T06:42:25+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/\"},\"wordCount\":2756,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/feature-image-c.jpg\",\"keywords\":[\"document database\",\"odm\"],\"articleSection\":[\"Data Modeling\",\"Node.js\",\"Ottoman.js ODM\",\"Tools &amp; SDKs\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/\",\"name\":\"Ottoman: Object Data Modeler (ODM) for Couchbase Node.js SDK\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/feature-image-c.jpg\",\"datePublished\":\"2021-03-30T16:13:45+00:00\",\"dateModified\":\"2025-06-14T06:42:25+00:00\",\"description\":\"Ottoman is an Object Data Modeler (ODM) for Couchbase\u2019s Node.js SDK providing JSON schema and validation for NoSQL. Learn why to use an ODM for Couchbase.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/feature-image-c.jpg\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/feature-image-c.jpg\",\"width\":1200,\"height\":628,\"caption\":\"Introduction to Ottoman\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Introduction to Ottoman With Couchbase\"}]},{\"@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\/67d3a4b597e42370ccd34b715a6b1f4c\",\"name\":\"Eric Bishard\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/b7d1d2580c41d35a21654fb1abe65d23\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a316a2658772914defd259571b8cad18878eb23c9d0cc3a97dd803deca0c09ca?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/a316a2658772914defd259571b8cad18878eb23c9d0cc3a97dd803deca0c09ca?s=96&d=mm&r=g\",\"caption\":\"Eric Bishard\"},\"description\":\"International speaker, blogging and advocating for the JavaScript, React, GraphQL and NoSQL community working as a Senior Developer Advocate for Couchbase.\",\"sameAs\":[\"https:\/\/www.reactstateofmind.com\",\"https:\/\/www.linkedin.com\/in\/eric-b\/\",\"https:\/\/x.com\/httpJunkie\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/pt\/author\/eric-bishard\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Ottoman: Object Data Modeler (ODM) for Couchbase Node.js SDK","description":"Ottoman is an Object Data Modeler (ODM) for Couchbase\u2019s Node.js SDK providing JSON schema and validation for NoSQL. Learn why to use an ODM for Couchbase.","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\/introduction-to-ottoman-with-couchbase\/","og_locale":"pt_BR","og_type":"article","og_title":"Introduction to Ottoman With Couchbase","og_description":"Ottoman is an Object Data Modeler (ODM) for Couchbase\u2019s Node.js SDK providing JSON schema and validation for NoSQL. Learn why to use an ODM for Couchbase.","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/introduction-to-ottoman-with-couchbase\/","og_site_name":"The Couchbase Blog","article_published_time":"2021-03-30T16:13:45+00:00","article_modified_time":"2025-06-14T06:42:25+00:00","og_image":[{"width":1200,"height":628,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/feature-image-c.jpg","type":"image\/jpeg"}],"author":"Eric Bishard","twitter_card":"summary_large_image","twitter_creator":"@httpJunkie","twitter_misc":{"Written by":"Eric Bishard","Est. reading time":"13 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/"},"author":{"name":"Eric Bishard","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/67d3a4b597e42370ccd34b715a6b1f4c"},"headline":"Introduction to Ottoman With Couchbase","datePublished":"2021-03-30T16:13:45+00:00","dateModified":"2025-06-14T06:42:25+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/"},"wordCount":2756,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/feature-image-c.jpg","keywords":["document database","odm"],"articleSection":["Data Modeling","Node.js","Ottoman.js ODM","Tools &amp; SDKs"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/","url":"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/","name":"Ottoman: Object Data Modeler (ODM) for Couchbase Node.js SDK","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/feature-image-c.jpg","datePublished":"2021-03-30T16:13:45+00:00","dateModified":"2025-06-14T06:42:25+00:00","description":"Ottoman is an Object Data Modeler (ODM) for Couchbase\u2019s Node.js SDK providing JSON schema and validation for NoSQL. Learn why to use an ODM for Couchbase.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/feature-image-c.jpg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/03\/feature-image-c.jpg","width":1200,"height":628,"caption":"Introduction to Ottoman"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/introduction-to-ottoman-with-couchbase\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Introduction to Ottoman With Couchbase"}]},{"@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\/67d3a4b597e42370ccd34b715a6b1f4c","name":"Eric Bishard","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/b7d1d2580c41d35a21654fb1abe65d23","url":"https:\/\/secure.gravatar.com\/avatar\/a316a2658772914defd259571b8cad18878eb23c9d0cc3a97dd803deca0c09ca?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a316a2658772914defd259571b8cad18878eb23c9d0cc3a97dd803deca0c09ca?s=96&d=mm&r=g","caption":"Eric Bishard"},"description":"Palestrante internacional, blogueiro e defensor da comunidade JavaScript, React, GraphQL e NoSQL, trabalhando como defensor s\u00eanior de desenvolvedores da Couchbase.","sameAs":["https:\/\/www.reactstateofmind.com","https:\/\/www.linkedin.com\/in\/eric-b\/","https:\/\/x.com\/httpJunkie"],"url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/eric-bishard\/"}]}},"authors":[{"term_id":8922,"user_id":53002,"is_guest":0,"slug":"eric-bishard","display_name":"Eric Bishard","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/a316a2658772914defd259571b8cad18878eb23c9d0cc3a97dd803deca0c09ca?s=96&d=mm&r=g","author_category":"","last_name":"Bishard","first_name":"Eric","job_title":"","user_url":"https:\/\/www.reactstateofmind.com","description":"Palestrante internacional, blogueiro e defensor da comunidade JavaScript, React, GraphQL e NoSQL, trabalhando como defensor s\u00eanior de desenvolvedores da Couchbase."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/10947","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\/53002"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=10947"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/10947\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/11030"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=10947"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=10947"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=10947"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=10947"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}