O Ottoman é um Object Data Modeler (ODM) para o SDK Node.js do Couchbase que fornece esquema e validação JSON para NoSQL.

Por que usar um ODM para o Couchbase

Com o Ottoman, você declara o esquema em seu código. Embora o Couchbase não tenha imposição de esquema para seus documentos, a maioria dos aplicativos precisa de algum nível de esquema, mesmo no NoSQL. Vamos explorar como obter o esquema e a validação no NoSQL usando o Ottoman e o Couchbase.

É importante validar se os documentos atendem a determinados requisitos antes de persistir. Embora o Ottoman crie uma abstração sobre o SDK do Couchbase, as vantagens superam as desvantagens. Um desenvolvedor cria muita lógica para criar e atualizar documentos, escrever o ciclo de vida pré/pós, trabalhar com estruturas de dados e validação.

Banco de dados NoSQL e projeto de esquema

Um ODM desempenha uma função semelhante no NoSQL e em um banco de dados relacional, mas com benefícios adicionais. O Couchbase não impõe validação, pois é flexível em termos de esquema. O Ottoman pode realizar determinadas verificações à 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ários tipos de documentos.

O código do aplicativo do servidor é um ótimo lugar para aplicar lógica e validação de negócios. O objetivo do Ottoman é proporcionar uma melhor experiência de desenvolvimento, além de oferecer controle sobre o esquema e a validação ao usar o Couchbase com o Node. Queremos oferecer aos desenvolvedores uma ferramenta confiável para criar sistemas que sejam fáceis de projetar, manter e dimensionar.

Object Data Mapping in Node.js with Ottoman for Couchbase

O Couchbase é um banco de dados NoSQL

O Couchbase Server é um banco de dados de documentos sem esquema, categorizado como um armazenamento de dados NoSQL, mas essa não é a melhor descrição, pois o Couchbase usa uma variante do SQL para fazer consultas, chamada N1QL. O fato de um esquema não ser rigorosamente aplicado em bancos de dados NoSQL como o Couchbase não significa que você não deva aplicá-lo.

Com o Couchbase, você obtém os benefícios do dimensionamento de nível empresarial, nós em cluster e a capacidade de armazenar e recuperar dados em um formato JSON.

Se você estiver familiarizado com o Mongoose, um ODM para MongoDB, você se sentirá bastante confortável com o Ottoman, pois eles têm muitos recursos que se sobrepõem, já que ambos são feitos para NodeJS e usados para modelar e persistir dados em um banco de dados de valores-chave orientado a documentos JSON.

Documento vs. Relacional Banco de dados

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ê verá uma comparação lado a lado dos dados que representam um hotel.

À esquerda, temos um documento que pode armazenar números de telefone em uma matriz, o que nos permite armazenar vários números de telefone de um único hotel. Para fazer isso em um banco de dados relacional, você certamente precisaria de uma nova tabela e manter um relacionamento entre as duas usando chaves primárias.

NoSQL Documents vs. Relational Tables in SQL

Para obter mais informações sobre modelagem de documentos, confira os recursos que reuni em uma postagem do blog: Guia de modelagem de dados JSON

No Ottoman, temos muitas construções para ajudar a definir o esquema e os modelos no nível do aplicativo. Vamos examinar alguns dos termos mais importantes que você precisa conhecer no Ottoman.

Tipos

Como visto em rosa na imagem acima, as propriedades do documento com o tipo de nome no Couchbase são quase equivalentes às tabelas em um banco de dados relacional. Elas podem ajudar a agrupar diferentes tipos de documentos JSON para fins de indexação. Ao usar índices secundários 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ê normalmente quiser pesquisar hotéis com base na cidade ou no estado, convém criar um Índice Secundário Composto que só precise pesquisar os cem documentos em que a cidade ou o estado seja igual a um determinado valor. Isso é muito mais eficiente do que usar, por exemplo, um índice primário.

Saiba mais sobre a indexação no Couchbase!

Coleções

Semelhante aos tipos no Couchbase 6.x (versão principal mais recente do Couchbase no momento em que este artigo foi escrito) e não mostrado na ilustração acima, as coleções serão favorecidas no Couchbase 7 (já em versão beta). No caso de usar coleções, você simplesmente não teria um 'tipo' em cada documento e, em vez disso, ter o documento atribuído a uma propriedade 'hotel' coleção.

Documentos

Comparável a linhas de dados em um banco de dados relacional. Os sistemas RDBMS tradicionais fazem referência a documentos relacionados de outras tabelas, como visto na ilustração acima. No entanto, também é possível fazer isso com um documento JSON; sugere-se incluir essas informações como um documento incorporado quando possível, como vemos na propriedade de número de telefone do documento do hotel, que é uma matriz de números de telefone. Embora seja um exemplo muito simples, pense que se você tivesse uma propriedade de endereço que fosse outro objeto JSON com muitas propriedades, você poderia pensar que ela precisaria ter seu próprio documento, mas aninhar essas informações no documento pai, na maioria dos casos, não tem problema.

Campos

Também conhecidos como atributos, são semelhantes às colunas em um banco de dados relacional e, com o Ottoman, você pode criar requisitos em nível de campo como parte do seu esquema.

Esquema

Embora o Couchbase não tenha esquema ou seja flexível, ainda podemos impor a estrutura no nível do aplicativo para nossos documentos.

Modelo

Um método construtor que recebe um esquema e cria uma instância de um documento equivalente a um único registro em um banco de dados relacional. Essa instância de documento pode ser construída e depois persistida no Couchbase pelo Ottoman usando o salvar() método.

Primeiros passos

Vamos começar a criar um aplicativo de demonstração que podemos usar para nos familiarizarmos com o Ottoman como um mapeador de documentos de objetos.

Instalação do Couchbase

Antes de começarmos, vamos configurar o Couchbase.

Você pode escolher entre uma das seguintes opções (estamos usando a opção #1 para este artigo):

  1. Instalar o Couchbase Server usando o Docker
  2. Faça o download do Couchbase específico para seu sistema operacional no site Site do Couchbase

Vamos navegar por alguns dos conceitos básicos do Ottoman implementando um modelo que representa os dados de um exemplo simplificado de companhia aérea, mantendo a tradição do conjunto de dados Travel-Sample do Couchbase.

Estou usando o Visual Studio Code, o NodeJS v12.14 e o NPM 6.14.8, portanto, você precisará ter o Node.js instalado em seu computador.

Inicializando nosso projeto com o NPM

Crie um diretório, inicialize nosso projeto, instale o Ottoman.js e abra-o no VS Code

Abra o terminal no editor de sua preferência. Eu adicionei um comando no final que abrirá no VS Code.

Conexão com o Couchbase com o Ottoman

Começaremos a trabalhar a partir do arquivo ./createAirline.js na raiz do projeto e adicione o seguinte (com base na configuração padrão):

Juntos, eles importam o pacote ottoman e especificam a coleção padrão (estilo do Couchbase Server 6.x)

Esquema e modelos otomanos

Os modelos são construtores sofisticados compilados a partir de definições de esquema. Uma instância de um modelo é chamada de documento. Os modelos no Ottoman ajudam você a criar, ler, atualizar e excluir facilmente documentos no banco de dados do Couchbase.

A criação de um modelo de otomana inclui alguns aspectos:

Definição de um esquema de documento

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ção.

Aqui definimos três propriedades (indicativo, país, nome) em nosso esquema, todos do tipo Cordas. Especificando um tipo para cada uma das propriedades do nosso modelo,  mapeia para um validador interno que será acionado quando o modelo for salvo no banco de dados e falhará se o tipo de dados do valor não for do tipo Cordas.

Os seguintes tipos de esquema são permitidos:

Definição de um modelo de documento

Precisamos chamar o construtor do modelo na instância do ottoman e passar a ele o nome da coleção e uma referência à definição do esquema.

Quando você chama o modelo() ela cria uma cópia do esquema e compila o modelo para você.

Vamos também dar o airlineSchema uma propriedade de número de telefone. Podemos adicionar uma função de validação que garantirá que o valor seja um número de telefone válido. Substitua a função airlineSchema com esses três blocos de código:

No exemplo acima, mostrei como criar um validador personalizado. Acontece que estamos usando uma expressão regular como check-in do nosso validador. Entenda que você pode ter qualquer lógica dentro de um desses validadores e, daqui a pouco, mostrarei um bom truque para reduzir nosso código, considerando que estamos usando uma expressão regular para a correspondência dos números de telefone.

Definição de validadores

Validadores registrado com Ottoman (como fizemos aqui com o ottoman.addValidators() ) será chamado uma vez para cada valor que a propriedade do nosso documento tiver na matriz. Se a propriedade não tivesse uma matriz e, em vez disso, tivesse apenas um único valor String, o validador seria executado apenas uma vez. Por esse motivo, imprimo o número de telefone problemático se a validação falhar.

No entanto, há uma maneira mais fácil de validar qualquer valor de propriedades do documento, desde que a verificação que você está realizando use uma expressão regular. A expressão ValidatorOption pode tomar um regexp e mensagem como um argumento, para que possamos reduzir nosso código para:

Como você pode ver, podemos fazer tudo o que estávamos fazendo antes em linha ao criar um novo esquema. Mas não deixe que isso o impeça de entender como criar um validador personalizado. Às vezes, precisamos de lógica adicional e é por isso que o primeiro exemplo ainda é algo que vale a pena conhecer.

Básico Operações de documentos em NoSQL

A maioria das operações básicas é abordada em nossa documentação do Ottoman V2. Abordaremos algumas delas aqui, mas sinta-se à vontade para mergulhar em nossa Documentos do Ottoman V2 (alfa) e nos informe se houver algo que você não consiga encontrar ou não entenda.

Criar documentos

Considerando o código que já examinamos acima, que cria um esquema, um modelo e validadores. Salvar um modelo e persisti-lo no banco de dados é muito fácil. Vamos criar um novo Companhia aérea usando nosso modelo Esquema e, em seguida, salvá-lo/persisti-lo no banco de dados.

Você pode estar se perguntando por que não chamamos apenas o saveDocument() por si só. Em vez disso, nós a chamamos após a função ottoman.start() está concluída. O iniciar é um atalho para executar o método ensureCollections e ensureIndexes. Tudo o que você precisa saber por enquanto é que esse método garante que os índices apropriados relacionados ao Ottoman tenham sido criados no Couchbase, e isso é importante para garantir que possamos executar coisas como o find() e usar ferramentas como o método Criador de consultas que será abordado no final do artigo.

Neste ponto, se você executasse todo o código que escrevemos usando o Node, nosso documento seria salvo no banco de dados:

O resultado dessa operação:

Os seguintes campos são retornados:

  1. Os campos de indicativo, país e nome são todos String, o valor mais básico que podemos ter em um documento.
  2. O campo id é gerado automaticamente pelo Couchbase e é uma chave exclusiva. O valor do ID é o que você usará em qualquer caso para encontrar um documento com o Ottoman em métodos como findByID ou removeByID
  3. O campo telefone é representado por uma matriz e contém números de telefone válidos.
  4. O O campo _type pode nos ajudar a organizar nossos documentos como uma tabela faz em um banco de dados relacional, No Couchbase 7, podemos usar coleções e escopos.
Erros de validação

Se inserirmos um número de telefone inválido e executarmos nó createAirline.js esse arquivo novamente, receberíamos uma mensagem de erro:

DICA: você pode definir sua conexão, esquema e modelos em arquivos separados, exportá-los e usá-los em outros arquivos. Crie um novo arquivo chamado modelo de esquema de companhia aérea.js e mover nosso esquema e definição de modelo para ele:

Agora podemos criar alguns arquivos novos, findAirline.js, updateAirline.jse removeAirline.js e preencha cada arquivo com o seguinte:

Isso nos ajudará a separar parte do nosso código para que não o repitamos em cada arquivo e, à medida que analisarmos cada uma das operações CRUD, poderemos simplesmente adicionar algum código a cada arquivo, e nosso esquema e modelo já serão importados.

Localizar documentos

Vamos tentar recuperar o registro que salvamos no banco de dados anteriormente. A classe de modelo expõe vários métodos estáticos e de instância para executar operações no banco de dados. Agora tentaremos encontrar o registro que criamos anteriormente usando o método find e passando o indicativo como termo de pesquisa. Vamos criar um novo arquivo chamado findAirline.js e podemos adicionar o seguinte código:

Localizar resultado do documento:

Atualizar documentos

Vamos modificar o registro acima, encontrando-o usando o indicativo de chamada, que podemos presumir que será um campo exclusivo em nossos dados, e então poderemos atualizar o documento em uma única operação.

Localize o documento e atualize o resultado:

Remover documentos

O Ottoman tem vários métodos que lidam com a remoção de documentos: remover, removeById e removeMany. Considerando os muitos exemplos que tivemos até agora, cada um deles deve ser muito fácil de entender como usar, portanto, forneceremos apenas um exemplo simples aqui para mostrar como remover um documento que já encontramos usando o find() método.

O resultado da remoção do documento é um simples valor do casusado para rastrear alterações nos documentos do Couchbase.

Middleware

Já vimos nosso middleware em ação, nosso validador que criamos inicialmente pode aproveitar o middleware usando funções que são executadas em estágios específicos de um pipeline, passando o controle durante a execução de funções assíncronas.

Ganchos disponíveis

  • validar
  • salvar
  • atualização
  • remover

Exemplo de middleware (também conhecido como pré e pós-ganchos)

Vamos tentar um exemplo simplesmente gerando um registro no console antes e depois da criação (salvamento) de um documento. Vou criar um novo arquivo chamado createWithHooks.js e a maior parte do código parecerá familiar, exceto pelo fato de eu ter adicionado ganchos pré e pós que apenas nos informarão o nome do documento antes do salvamento e o ID do documento depois do salvamento:

Salvar o resultado do documento:

Recebemos nossas mensagens antes e depois do salvamento. Com a validação, você pode garantir que determinados valores de propriedade do documento atendam aos seus critérios. O acesso ao ciclo de vida quando o documento é salvo, atualizado e removido também nos ajudou a ter um controle sobre o middleware Ottoman! 

Criação de consultas

O Ottoman tem uma API muito rica que lida com muitas operações complexas compatíveis com o Couchbase e o N1QL. Nosso construtor de consultas nos bastidores cria suas instruções N1QL para você. Ao usar o Query Builder, você tem três opções de qual modo usar. 

  1. Usando parâmetros
  2. Funções de acesso
  3. ou usando Parâmetros e Funções de Acesso

Nos próximos três exemplos, farei a mesma coisa usando cada um dos três modos diferentes do QueryBuilder (parâmetros, funções de acesso e modo misto). Cada exemplo terá:

  1. Selecione nome e país da Companhia Aérea
  2. Onde o país O valor é "United States" (Estados Unidos)
  3. E LIMITAR nossos resultados a 10

Vamos primeiro criar um novo arquivo chamado: findWithQueryBuilder.jse adicione o seguinte código:

Esse arquivo tem um comentário no meio que diz: "Substituir por um exemplo de QueryBuilder". Podemos simplesmente copiar qualquer um dos exemplos a seguir nesta seção para essa área do arquivo.

Parâmetros

Funções de acesso

Modo misto

Uma vez que você tenha criado um generateQuery() usando um dos modos mistos acima, você precisaria chamar de forma assíncrona a função generateQuery e executeQuery e o código para isso, como eu disse, funcionará com muitas variantes do código acima:

Um resultado de qualquer um dos três modos acima:

Recursos

Conclusão

Fizemos um tour guiado pelo Ottoman, adquirindo uma compreensão de muitos conceitos. Esquema, modelos, middleware, plug-ins, hooks e criação de consultas.

Exploramos como se conectar ao Couchbase no Ottoman. Definimos esquemas e modelos. Abordamos vários fundamentos do esquema e do design do banco de dados NoSQL. Por fim, examinamos algumas das operações CRUD mais úteis. Tudo para que você possa criar, ler, atualizar e excluir documentos no Couchbase via Ottoman.

Dê feedback e contribua

Espero que este artigo tenha desmistificado por que e como usar o Ottoman e o ODM para o Couchbase. Conforme demonstrado, você pode usar o Ottoman para projetar o esquema do banco de dados NoSQL, validar e reduzir o padrão. A escrita de operações CRUD é simplificada e ajuda no desenvolvimento rápido.

Se você tiver alguma dúvida sobre o Ottoman, quiser ajudar a contribuir com esse projeto de código aberto ou apenas quiser dizer olá, meu nome é Eric Bishard e sou o Developer Advocate aqui na Couchbase, com foco na experiência do desenvolvedor de Node.js e JavaScript. Twitter/@httpJunkie.

Autor

Postado por Eric Bishard

Palestrante internacional, blogueiro e defensor da comunidade JavaScript, React, GraphQL e NoSQL, trabalhando como defensor sênior de desenvolvedores da Couchbase.

Deixar uma resposta