Explore o novo chatbot do Developer Center! O MongoDB AI chatbot pode ser acessado na parte superior da sua navegação para responder a todas as suas perguntas sobre o MongoDB .

Junte-se a nós no Amazon Web Services re:Invent 2024! Saiba como usar o MongoDB para casos de uso de AI .
Desenvolvedor do MongoDB
Central de desenvolvedor do MongoDBchevron-right
Produtoschevron-right
Atlaschevron-right

Múltiplas conexões MongoDB em um único aplicativo

Vishal Turi10 min read • Published Nov 08, 2023 • Updated Apr 02, 2024
Node.jsAtlasJavaScript
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
O MongoDB, um popular banco de dados NoSQL, é amplamente utilizado em vários aplicativos e cenários. Embora uma única conexão de banco de dados possa atender adequadamente às necessidades de vários projetos, existem cenários específicos e vários casos de uso do mundo real que destacam as vantagens de empregar várias conexões.
Neste artigo, veremos o conceito de estabelecer múltiplas conexões do MongoDB em um único aplicativo Node.js.

Explorando a necessidade de várias conexões com o MongoDB: casos de uso e exemplos

No mundo do MongoDB e dos aplicativos baseados em dados, a demanda por múltiplas conexões do MongoDB está aumentando. Vamos explorar por que essa necessidade surge e descobrir casos de uso e exemplos do mundo real em que várias conexões fornecem uma solução vital.
Setores como e-commerce, jogos, serviços financeiros, mídia, entretenimento e Internet das Coisas (IoT) geralmente sofrem com volumes substanciais de dados ou dados de diversas fontes.
Por exemplo, imagine um aplicativo da web que distribui o tráfego uniformemente entre vários servidores MongoDB usando várias conexões ou uma arquitetura de microsserviços em que cada microsserviço acessa o banco de dados por meio de sua conexão dedicada. Talvez em um aplicativo de processamento de dados, várias conexões permitam a recuperação de dados de vários servidores MongoDB simultaneamente. Mesmo um aplicativo de backup pode empregar várias conexões para fazer backup eficiente de dados de vários servidores MongoDB para um único servidor de backup.
Além disso, considere um aplicativo multilocatário em que diferentes locatários ou clientes compartilham o mesmo aplicativo da web, mas exigem bancos de dados separados e isolados. Nesse cenário, cada locatário pode ter sua própria conexão do MongoDB dedicada. Isso garante a separação, a segurança e a personalização de dados para cada locatário enquanto todos operam no mesmo aplicativo. Essa abordagem simplifica o gerenciamento e fornece uma maneira eficiente de dimensionar à medida que novos locatários ingressam na plataforma sem afetar os existentes.
Antes de nos aprofundarmos na implementação prática, vamos apresentar alguns conceitos-chave que serão relevantes nos próximos exemplos de casos de uso. Considere vários casos de uso, como balanceamento de carga, fragmentação, réplicas de leitura, isolamento e tolerância a falhas. Esses conceitos executam um papel crucial em cenários onde múltiplas conexões MongoDB são necessárias para gerenciamento eficiente de dados e otimização de desempenho.

Pré-requisitos

Ao longo deste guia, usaremos Node.js, Express.js e o pacote Mongoose NPM para gerenciar interações com o MongoDB. Antes de prosseguir, certifique-se de que seu ambiente de desenvolvimento esteja pronto e que você tenha essas dependências instaladas.
Se você é iniciante no MongoDB ou nunca configurou o MongoDB, o primeiro passo é configurar uma conta do MongoDB Atlas. Veja instruções passo a passo sobre como fazer isso no artigo Primeiros passos com o Atlas do MongoDB.
Esta publicação usa MongoDB 6.3.2 e Node.js 18.17.1
Se você estiver planejando criar um novo projeto, comece criando um novo diretório para seu projeto. Em seguida, inicie um novo projeto usando o comandonpm init.
Se você já tiver um projeto existente e quiser integrar essas dependências, verifique se o diretório do projeto está aberto. Nesse caso, você só precisa instalar as dependências do Express e do Mongoose, caso ainda não o tenha feito, certificando-se de especificar os números das versões para evitar possíveis conflitos.
1npm i express@4.18.2 mongoose@7.5.3
Esteja ciente de que o Mongoose não é o driver oficial do MongoDB, mas uma biblioteca popular de modelagem de dados de objetos (ODM) para o MongoDB. Se preferir usar o driver oficial do MongoDB, você pode encontrar a documentação relevante no site oficial do MongoDB.
A próxima etapa é configurar o arquivo de ambiente .env, caso ainda não o tenha feito. Definiremos variáveis para as strings de conexão do MongoDB que usaremos ao longo deste artigo. A variável PRIMARY_CONN_STR é para a string de conexão primária do MongoDB, e a variável SECONDARY_CONN_STR é para a string de conexão secundária do MongoDB.
1PRIMARY_CONN_STR=mongodb+srv://…
2SECONDARY_CONN_STR=mongodb+srv://…
Se você for iniciante no MongoDB e precisar de orientação para obter uma string de conexão MongoDB do Atlas, consulte o artigo Obter string de conexão.
Agora, dividiremos o processo de conexão em duas partes: uma para a conexão primária e outra para a conexão secundária.
Agora, vamos começar configurando a conexão primária.

Configurando a conexão primária do MongoDB

O processo de conexão principal pode ser familiar se você já o tiver implementado em seu aplicativo. Mesmo assim, fornecerei uma explicação detalhada para maior clareza. Os leitores que já estão familiarizados com esse processo podem pular esta seção.
Normalmente, utilizamos o método mongoose.connect() para estabelecer a conexão primária com o MongoDB database para o nosso aplicativo, pois ele gerencia com eficiência um único pool de conexões para todo o aplicativo.
Em um arquivo separado chamado db.primary.js, definimos um método de conexão que usaremos em nosso arquivo do aplicativo principal (por exemplo, index.js). Este método, mostrado abaixo, configura a conexão do MongoDB e gerencia eventos:
1const mongoose = require("mongoose");
2
3module.exports = (uri, options = {}) => {
4 // By default, Mongoose skips properties not defined in the schema (strictQuery). Adjust it based on your configuration.
5 mongoose.set('strictQuery', true);
6
7 // Connect to MongoDB
8 mongoose.connect(uri, options)
9 .then()
10 .catch(err => console.error("MongoDB primary connection failed, " + err));
11
12 // Event handling
13 mongoose.connection.once('open', () => console.info("MongoDB primary connection opened!"));
14 mongoose.connection.on('connected', () => console.info("MongoDB primary connection succeeded!"));
15 mongoose.connection.on('error', (err) => {
16 console.error("MongoDB primary connection failed, " + err);
17 mongoose.disconnect();
18 });
19 mongoose.connection.on('disconnected', () => console.info("MongoDB primary connection disconnected!"));
20
21 // Graceful exit
22 process.on('SIGINT', () => {
23 mongoose.connection.close().then(() => {
24 console.info("Mongoose primary connection disconnected through app termination!");
25 process.exit(0);
26 });
27 });
28}
A próxima etapa é criar esquemas para realizar operações em seu aplicativo. Escreveremos o esquema em um arquivo separado chamado product.schema.js e o exportaremos. Vamos dar um exemplo de esquema para produtos em um aplicativo de lojas:
1const mongoose = require("mongoose");
2
3module.exports = (options = {}) => {
4 // Schema for Product
5 return new mongoose.Schema(
6 {
7 store: {
8 _id: mongoose.Types.ObjectId, // Reference-id to the store collection
9 name: String
10 },
11 name: String
12 // add required properties
13 },
14 options
15 );
16}
Agora, vamos importar o arquivo db.primary.js em nosso arquivo principal (por exemplo, index.js) e usar o método definido lá para estabelecer a conexão primária do MongoDB. Você também pode passar um objeto de opções de conexão opcional, se necessário.
Depois de configurar a conexão primária do MongoDB, você importa o arquivo product.schema.js para acessar o esquema do produto. Isso permite criar um modelo e executar operações relacionadas a produtos em seu aplicativo:
1// Primary Connection (Change the variable name as per your .env configuration!)
2// Establish the primary MongoDB connection using the connection string variable declared in the Prerequisites section.
3require("./db.primary.js")(process.env.PRIMARY_CONN_STR, {
4 // (optional) connection options
5});
6
7// Import Product Schema
8const productSchema = require("./product.schema.js")({
9 collection: "products",
10 // Pass configuration options if needed
11});
12
13// Create Model
14const ProductModel = mongoose.model("Product", productSchema);
15
16// Execute Your Operations Using ProductModel Object
17(async function () {
18 let product = await ProductModel.findOne();
19 console.log(product);
20})();
Agora, vamos configurar uma conexão secundária ou segunda conexão do MongoDB para cenários em que seu aplicativo exige múltiplas conexões do MongoDB.

Configurar conexões secundárias do MongoDB

Dependendo dos requisitos do seu aplicativo, você pode configurar conexões secundárias do MongoDB para vários casos de uso. Mas, antes disso, criaremos um código de conexão em um arquivo db.secondary.js, usando especificamente o método mongoose.createConnection(). Esse método nos permite estabelecer pools de conexões separados, cada um personalizado para um caso de uso ou padrão de acesso a dados específicos, diferentemente do método mongoose.connect() que usamos anteriormente para a conexão primária do MongoDB:
1const mongoose = require("mongoose");
2
3module.exports = (uri, options = {}) => {
4 // Connect to MongoDB
5 const db = mongoose.createConnection(uri, options);
6
7 // By default, Mongoose skips properties not defined in the schema (strictQuery). Adjust it based on your configuration.
8 db.set('strictQuery', true);
9
10 // Event handling
11 db.once('open', () => console.info("MongoDB secondary connection opened!"));
12 db.on('connected', () => console.info(`MongoDB secondary connection succeeded!`));
13 db.on('error', (err) => {
14 console.error(`MongoDB secondary connection failed, ` + err);
15 db.close();
16 });
17 db.on('disconnected', () => console.info(`MongoDB secondary connection disconnected!`));
18
19 // Graceful exit
20 process.on('SIGINT', () => {
21 db.close().then(() => {
22 console.info(`Mongoose secondary connection disconnected through app termination!`);
23 process.exit(0);
24 });
25 });
26
27 // Export db object
28 return db;
29}
Agora, vamos importar o arquivodb.secondary.js em nosso arquivo principal (por exemplo, index.js), criar o objeto de conexão com uma variável chamada dbe usar o método definido lá para estabelecer a conexão secundária do MongoDB. Você também pode passar um objeto de opções de conexão opcional, se necessário:
1// Secondary Connection (Change the variable name as per your .env configuration!)
2// Establish the secondary MongoDB connection using the connection string variable declared in the Prerequisites section.
3const db = require("./db.secondary.js")(process.env.SECONDARY_CONN_STR, {
4 // (optional) connection options
5});
Agora que já temos a conexão pronta, você pode usar esse objeto db para criar um modelo. Exploramos diferentes cenários e exemplos para ajudar você a escolher a configuração que melhor se alinha às suas necessidades específicas de acesso e gerenciamento de dados:

1. Usando o esquema existente

Você pode optar por usar o mesmo arquivo de esquema product.schema.js que foi empregado na conexão primária. Isso é adequado para cenários em que ambas as conexões operam no mesmo modelo de dados.
Importe o arquivo product.schema.js para acessar o esquema do produto. Isso permite criar um modelo usando o objetodb e executar operações relacionadas a produtos em seu aplicativo:
1// Import Product Schema
2const secondaryProductSchema = require("./product.schema.js")({
3 collection: "products",
4 // Pass configuration options if needed
5});
6
7// Create Model
8const SecondaryProductModel = db.model("Product", secondaryProductSchema);
9
10// Execute Your Operations Using SecondaryProductModel Object
11(async function () {
12 let product = await SecondaryProductModel.findOne();
13 console.log(product);
14})();
Para ver um exemplo de código prático e os recursos disponíveis para usar o esquema existente de uma conexão de banco de dados primária em uma conexão secundária do MongoDB em seu projeto, visite o repositório do GitHub.

2. Definindo a flexibilidade do esquema

Ao trabalhar com várias conexões do MongoDB, é essencial ter a flexibilidade de adaptar seu esquema com base em casos de uso específicos. Embora a conexão primária possa exigir um esquema rigoroso com validação para garantir a integridade dos dados, há cenários em que uma conexão secundária tem uma finalidade diferente. Por exemplo, uma conexão secundária pode armazenar dados para análise em um servidor de arquivamento, com requisitos de esquema variados, orientados por casos de uso anteriores. Nesta seção, exploraremos como configurar a flexibilidade de esquema para sua conexão secundária, permitindo que você atenda às necessidades distintas de seu aplicativo.
Se preferir ter flexibilidade de esquema no mongoose, você pode passar a propriedade strict: false nas opções ao configurar o esquema para a conexão secundária. Isso permite trabalhar com dados que não aderem estritamente ao esquema.
Importe o arquivo product.schema.js para acessar o esquema do produto. Isso permite criar um modelo usando o objetodb e executar operações relacionadas a produtos em seu aplicativo:
1// Import Product Schema
2const secondaryProductSchema = require("./product.schema.js")({
3 collection: "products",
4 strict: false
5 // Pass configuration options if needed
6});
7
8// Create Model
9const SecondaryProductModel = db.model("Product", secondaryProductSchema);
10
11// Execute Your Operations Using SecondaryProductModel Object
12(async function () {
13 let product = await SecondaryProductModel.findOne();
14 console.log(product);
15})();
Para ver um exemplo de código prático e os recursos disponíveis para definir a flexibilidade do esquema em uma conexão secundária do MongoDB em seu projeto, visite o repositório do GitHub.

3. Alternando bancos de dados dentro da mesma conexão

Na configuração do banco de dados do seu aplicativo, você pode alternar perfeitamente entre diferentes bancos de dados usando o método db.useDb(). Esse método permite criar um novo objeto de conexão associado a um banco de dados específico e também compartilha o mesmo pool de conexões.
Essa abordagem permite gerenciar com eficiência vários banco de dados em seu aplicativo, usando uma única conexão e mantendo contextos de dados distintos para cada banco de dados.
Importe o arquivo product.schema.js para acessar o esquema do produto. Isso permite que você crie um modelo usando o objeto db e execute operações relacionadas a produtos em seu aplicativo.
Agora, para fornecer um exemplo em que uma loja pode ter seu próprio banco de dados contendo usuários e produtos, você pode incluir o seguinte cenário.
Exemplo de caso de uso: armazenamento com banco de dados separado
Imagine que você esteja desenvolvendo uma plataforma de e-commerce em que várias lojas operam de forma independente. Cada loja tem seu banco de dados para gerenciar seus produtos. Nesse cenário, você pode usar o método db.useDb() para alternar entre diferentes bancos de dados de armazenamento enquanto mantém um pool de conexões compartilhado:
1// Import Product Schema
2const secondaryProductSchema = require("./product.schema.js")({
3 collection: "products",
4 // strict: false // that doesn't adhere strictly to the schema!
5 // Pass configuration options if needed
6});
7
8// Create a connection for 'Store A'
9const storeA = db.useDb('StoreA');
10
11// Create Model
12const SecondaryStoreAProductModel = storeA.model("Product", secondaryProductSchema);
13
14// Execute Your Operations Using SecondaryStoreAProductModel Object
15(async function () {
16 let product = await SecondaryStoreAProductModel.findOne();
17 console.log(product);
18})();
19
20// Create a connection for 'Store B'
21const storeB = db.useDb('StoreB');
22
23// Create Model
24const SecondaryStoreBProductModel = storeB.model("Product", secondaryProductSchema);
25
26// Execute Your Operations Using SecondaryStoreBProductModel Object
27(async function () {
28 let product = await SecondaryStoreBProductModel.findOne();
29 console.log(product);
30})();
Neste exemplo, conexões de banco de dados separadas foram estabelecidas para Store A e Store B, cada uma contendo seus dados do produto. Essa abordagem fornece uma separação clara de dados e, ao mesmo tempo, utiliza de forma eficiente um único pool de conexões compartilhado para todas as lojas, aprimorando o gerenciamento de dados em uma plataforma de e-commerce de várias lojas.
Na seção anterior, demonstramos uma abordagem estática em que as conexões eram explicitamente criadas para cada armazenamento, e cada conexão era nomeada de acordo com isso (por exemplo, StoreA, StoreB).
Para introduzir uma abordagem dinâmica, você pode criar uma função que aceite o ID ou nome de uma loja como parâmetro e retorne um objeto de conexão. Essa função dinâmica permite alternar entre diferentes armazenamentos, fornecendo seus identificadores, e reutiliza eficientemente as conexões existentes quando possível.
1// Function to get connection object for particular store's database
2function getStoreConnection(storeId) {
3 return db.useDb("Store"+storeId, { useCache: true });
4}
5
6// Create a connection for 'Store A'
7const store = getStoreConnection("A");
8
9// Create Model
10const SecondaryStoreProductModel = store.model("Product", secondaryProductSchema);
11
12// Execute Your Operations Using SecondaryStoreProductModel Object
13(async function () {
14 let product = await SecondaryStoreProductModel.findOne();
15 console.log(product);
16})();
Na abordagem dinâmica, as instâncias de conexão são criadas e armazenadas em cache conforme necessário, eliminando a necessidade de gerenciar manualmente conexões separadas para cada loja. Essa abordagem aumenta a flexibilidade e a eficiência de recursos em cenários em que você precisa trabalhar com várias lojas em seu aplicativo.
Ao explorar esses exemplos, cobrimos uma série de cenários para o gerenciamento de vários bancos de dados na mesma conexão, oferecendo a flexibilidade necessária para adaptar a configuração do banco de dados às necessidades específicas do seu aplicativo. Agora você está preparado para gerenciar com eficiência contextos de dados distintos para vários casos de uso em seu aplicativo.
Para ver um exemplo de código prático e os recursos disponíveis para alternar bancos de dados dentro da mesma conexão em uma conexão MongoDB secundária em seu projeto, visite o repositório do GitHub.

Melhores práticas

Na busca por uma configuração do MongoDB robusta e eficiente em seu aplicativo Node.js, recomendamos as seguintes práticas. Essas diretrizes servem como base para uma implementação confiável, e eu sugiro considerá-las e implementá-las:
  • Pool de conexões: aproveite ao máximo o pool de conexões para gerenciar com eficiência as conexões do MongoDB, permitindo a reutilização de conexões e reduzindo a sobrecarga. Leia mais sobre pool de conexões.
  • Tratamento de erros: mecanismos robustos de tratamento de erros, registro abrangente e planos de contingência garantem a confiabilidade da sua configuração do MongoDB diante de problemas inesperados.
  • Segurança: priorize a segurança de dados com práticas de autenticação, autorização e comunicação segura, especialmente ao lidar com informações confidenciais. Leia mais sobre a Segurança do MongoDB.
  • Escalabilidade: planeje a escalabilidade desde o início, considerando estratégias de dimensionamento horizontal e vertical para acomodar o crescimento do seu aplicativo.
  • Testes: Ttestes abrangentes em vários cenários, como failover, alta carga e restrições de recursos, validam a resiliência e o desempenho de sua configuração de conexão múltipla com o MongoDB.

Conclusão

Aproveitar várias conexões do MongoDB em um aplicativo Node.js abre um mundo de possibilidades para diversos casos de uso, de e-commerce a sistemas multilocatários. Se você precisa aprimorar a separação de dados, escalar seu aplicativo com eficiência ou acomodar diferentes padrões de acesso aos dados, essas técnicas permitem adaptar a configuração do banco de dados às necessidades exclusivas do seu projeto. Com o conhecimento adquirido neste guia, você está bem preparado para gerenciar vários contextos de dados em um único aplicativo, garantindo interações robustas, flexíveis e eficientes com o MongoDB.

Recursos adicionais

  • Documentação do Mongoose: para uma compreensão profunda das conexões do Mongoose, navegue na documentação oficial do Mongoose.
  • Repositório Github: para mergulhar na implementação completa de várias conexões do MongoDB em um aplicativo Node.js que realizamos acima, visite o repositório Github. Sinta-se à vontade para clonar o repositório e experimentar diferentes casos de uso em seus projetos.
Se você tiver alguma dúvida ou feedback, confira os fóruns da MongoDB Community e deixe sua opinião.

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Artigo

Como habilitar o teste local e automático de recursos baseados na pesquisa do Atlas


Jun 12, 2024 | 8 min read
Tutorial

Consulta flexível com Atlas Search


Jul 12, 2024 | 3 min read
Tutorial

Construindo um Painel de Vendas Dinâmico e em Tempo Real no MongoDB


Aug 05, 2024 | 7 min read
Tutorial

Desenvolvimento sem servidor com Kotlin, AWS Lambda e MongoDB Atlas


Aug 01, 2023 | 6 min read
Sumário