Introdução ao MongoDB Kotlin Driver
Avalie esse Tutorial
This is an introductory article on how to build an application in Kotlin using MongoDB Atlas and the MongoDB Kotlin driver, the latest addition to our list of official drivers. Together, we'll build a CRUD application that covers the basics of how to use MongoDB as a database, while leveraging the benefits of Kotlin as a programming language, like data classes, coroutines, and flow.
Este é um artigo de introdução. Portanto, não é necessário muito como pré-requisito, mas a familiaridade com o Kotlin como linguagem de programação será útil.
Além disso, precisamos de uma conta do Atlas, que é gratuita para sempre. Crie uma conta, caso ainda não tenha. Isso fornece o MongoDB como um banco de dados em nuvem e muito mais. Mais adiante neste tutorial, usaremos essa conta para criar um novo cluster, carregar um conjunto de dados e, por fim, consultá-lo.
Em geral, o MongoDB é um banco de dados de documentos distribuído e multiplataforma que permite criar aplicativos com esquema flexível. Caso você não esteja familiarizado com ele ou queira fazer uma rápida recapitulação, recomendamos explorar a série MongoDB Jumpstart para se familiarizar com o MongoDB e seus vários serviços em menos 10 minutos. Ou, se preferir ler, siga nosso guia.
E, por último, para ajudar em nossas atividades de desenvolvimento, usaremos o Jetbrains IntelliJ IDEA (Community Edition), que tem suporte padrão para a linguagem Kotlin.
Antes de começarmos, gostaria de falar um pouco sobre o Realm Kotlin SDK, um dos SDKs usados para criar aplicações móveis do lado do cliente usando o ecossistema MongoDB. Ele não deve ser confundido com o driver MongoDB Kotlin para programação do lado do servidor. O driver MongoDB Kotlin, um driver de linguagem, permite que você interaja perfeitamente com o Atlas, um banco de dados em nuvem, com os benefícios do paradigma da linguagem Kotlin. É apropriado para criar aplicações de back-end, scripts, etc.
Para tornar o aprendizado mais significativo e prático, criaremos um aplicativo CRUD. Confira nosso repositório do Github se quiser acompanhar. Então, vamos começar.
Para criar o projeto, podemos usar o assistente de projeto, que pode ser encontrado nas opções de menu
File
. Em seguida, selecione New
, seguido de Project
. Isso abrirá a tela New Project
, conforme mostrado abaixo, e atualizará o projeto e a linguagem para Kotlin.Após a sincronização inicial do Gradle, nosso projeto está pronto para ser executado. Então, vamos tentar usar o ícone de execução na barra de menu ou simplesmente pressionar CRTL + R no Mac. Atualmente, nosso projeto não faz muito além de imprimir
Hello World!
e os argumentos fornecidos, mas a mensagem BUILD SUCCESSFUL
no console de execução é o que estamos procurando, o que nos informa que a configuração do projeto está concluída.Agora, a próxima etapa é adicionar o driver Kotlin ao nosso projeto, o que nos permite interagir com o MongoDB Atlas.
Adicionar o driver ao projeto é simples e direto. Basta atualizar o bloco
dependencies
com a dependência do driver Kotlin no arquivo de criação — ou seja, build.gradle
.Para se conectar ao banco de dados, primeiro precisamos do
Connection URI
que pode ser encontrado pressionando connect to cluster
em nossa conta Atlas, conforme mostrado abaixo.Com o URI de conexão disponível, a próxima etapa é criar um arquivo Kotlin.
Setup.kt
é onde gravamos o código para conexão com o MongoDB Atlas.A conexão com o nosso banco de dados pode ser feita em duas etapas. Primeiro, criamos uma instância do MongoClient usando
Connection URI
.Depois, use o cliente para se conectar ao banco de dados,
sample_restaurants
, um conjunto de dados de amostra para restaurantes. Um conjunto de dados de amostra é uma ótima maneira de explorar a plataforma e criar um POC mais realista para validar suas ideias. Para saber como propagar seu primeiro banco de dados Atlas com dados de amostra, visite a documentação.A codificação
connectionString
não é uma boa abordagem e pode levar a riscos de segurança ou à incapacidade de fornecer acesso baseado em função. Para evitar esses problemas e seguir as melhores práticas, usaremos variáveis de ambiente. Outras abordagens comuns são o uso do Vault, variáveis de configuração de compilação e variáveis de ambiente de CI/CD.Para adicionar variáveis de ambiente, use
Modify run configuration
, que pode ser encontrado clicando com o botão direito do mouse no arquivo.Juntamente com o código para acessar a variável de ambiente, nosso código final tem a seguinte aparência.
No trecho de código acima, ainda podemos usar uma string codificada. Isso é feito apenas para fins de demonstração, permitindo que você use um URI de conexão diretamente para facilitar e executar isso por meio de qualquer editor on-line. Mas é altamente recomendável evitar a codificação de um URI de conexão.
Com a função
setupConnection
pronta, vamos testá-la e realizar a query do banco de dados para obter a contagem e o nome da coleção.Ao executar esse código, nosso resultado fica assim:
Até agora, você deve ter notado que estamos usando a palavra-chave
suspend
com listAllCollection()
. listCollectionNames()
é uma função assíncrona, pois interage com o banco de dados e, portanto, idealmente seria executada em uma thread diferente. E como o driver Kotlin do MongoDB oferece suporte ao Coroutines, o paradigma de linguagem assíncrona, nativo do Kotlin, podemos nos beneficiar dele usando funções suspend
.Da mesma forma, para descartar coleções, usamos a função
suspend
.Com isso concluído, estamos prontos para começar a trabalhar em nosso aplicativo CRUD. Portanto, para começar, precisamos criar uma classe
data
que represente as informações do restaurante que nosso aplicativo salva no banco de dados.No trecho de código acima, usamos duas anotações:
@BsonId
, que representa a identidade exclusiva ou_id
de um documento.@BsonProperty
, que cria um alias para chaves no documento – por exemplo,restaurantId
representarestaurant_id
.
Observação: nossa classe
Restaurant
aqui é uma réplica exata de um documento de restaurante no conjunto de dados de exemplo, mas alguns campos podem ser ignorados ou marcados como opcionais - por exemplo, grades
e address
- enquanto mantém a capacidade de executar operações CRUD. Podemos fazer isso, pois o document model do MongoDB permite um esquema flexível para nossos dados.Com todo o trabalho pesado feito (10 linhas de código para conexão), adicionar um novo documento ao banco de dados é realmente simples e pode ser feito com uma linha de código usando
insertOne
. Então, vamos criar um novo arquivo chamado Create.kt
, que conterá todas as operações de criação.Quando o executamos, a saída no console é:
Reitero, não se esqueça de adicionar uma variável de ambiente novamente para este arquivo, se você teve problemas ao executá-lo.
Se quisermos adicionar vários documento à coleção, podemos usar
insertMany
, que é recomendado em vez da execução de insertOne
em um loop.Com esses resultados no console, podemos dizer que os dados foram adicionados com sucesso.
Mas e se quisermos ver o objeto no banco de dados? Uma maneira é com uma operação de leitura, que faríamos em breve ou usaríamos o MongoDB Compass para visualizar as informações.
O MongoDB Compass é uma ferramenta GUI interativa e gratuita para consultar, otimizar e analisar os dados do MongoDB em seu sistema. Para começar, baixe a ferramenta e use
connectionString
para se conectar ao banco de dados.Para ler as informações do banco de dados, podemos usar o operador
find
. Vamos começar lendo qualquer documento.O operador
find
retorna uma lista de resultados, mas como estamos interessados apenas em um único documento, podemos usar o operador limit
para limitar nosso conjunto de resultados. Nesse caso, seria um único documento.Se estendermos isso ainda mais e quisermos ler um documento específico, poderemos adicionar parâmetros de filtro sobre ele:
Para a saída, vemos isso:
Não se esqueça de adicionar a variável de ambiente novamente para este arquivo, se você teve problemas ao executá-lo.
Outro caso de uso prático que vem com uma operação de leitura é a paginação aos resultados. Isso pode ser feito com os operadores
limit
e offset
.Mas com essa abordagem, frequentemente, o tempo de resposta da query aumenta com o valor do
offset
. Para superar isso, podemos nos beneficiar criando um Index
, como mostrado abaixo.Agora, vamos discutir como editar/atualizar um documento existente. Novamente, vamos criar rapidamente um novo arquivo Kotlin,
Update.Kt
.Em geral, há duas maneiras de atualizar qualquer documento:
- Execute uma operação update, o que nos permite atualizar campos específicos dos documentos correspondentes sem afetar os outros campos.
- Execute uma operação replace para substituir o documento correspondente pelo novo documento.
Para este exercício, usaremos o documento que criamos anteriormente com a operação create
{restaurant_id: "restaurantId"}
e atualizaremos restaurant_id
com um valor mais realista. Vamos dividir isso em duas subtarefas para maior clareza.Primeiro, usando
Filters
, executamos uma query para filtrar o documento, semelhante à operação de leitura anterior.Então, podemos definir o
restaurant_id
com um valor inteiro aleatório usando Updates
.E, finalmente, usamos
updateOne
para atualizar o documento em uma operação atômica.No exemplo acima, já sabíamos qual documento queríamos atualizar – o restaurante com id
restauratantId
– mas poderia haver casos de uso em que essa não seria a situação. Nesses casos, primeiro procuraríamos o documento e depois o atualizaríamos. findOneAndUpdate
pode ser útil. Ele permite combinar esses dois processos em uma operação atômica, desbloqueando desempenho adicional.Outra variação do mesmo pode ser atualizar vários documentos com uma chamada.
updateMany
é útil para esses casos de uso - por exemplo, se quisermos atualizar o cuisine
de todos os restaurantes para seu tipo favorito de culinária e borough
para o Brooklyn.Nestes exemplos, usamos
set
e combine
com Updates
. Mas há muitos outros tipos de operador de atualização a serem analisados que nos permitem realizar muitas operações intuitivas, como definir currentDate ou o registro de data e hora, aumentar ou diminuir o valor do campo e assim por diante. Para saber mais sobre os diferentes tipos de operadores de atualização que você pode executar com Kotlin e MongoDB, consulte nossos documentos.Agora, vamos explorar uma última operação CRUD: excluir. Começaremos explorando como excluir um único documento. Para fazer isso, usaremos
findOneAndDelete
em vez de deleteOne
. Como benefício adicional, isso também retorna o documento excluído como saída. Em nosso exemplo, excluímos o restaurante:Para excluir vários documentos, podemos usar
deleteMany
. Podemos, por exemplo, usar isso para excluir todos os dados que criamos anteriormente com nossa operação de criação.Parabéns! Agora você sabe configurar seu primeiro aplicativo Kotlin com MongoDB e executar operações CRUD. O código-fonte completo do aplicativo pode ser encontrado no GitHub.
Se você tiver algum feedback sobre sua experiência de trabalho com o driver MongoDB Kotlin, envie um comentário em nosso portal de feedback do usuário ou entre em contato conosco no Twitter: @codeWithMohit.