Multidatabase with mongoose
Tags: database, mongodb
Published: 2024-01-16 13:01:52

## Introduction
At Woovi we always focus on the simplest software architecture that can support our product requirements.
Although we started using one database to support all our features, we decided to move some collections of logs to another database to reduce the load from the core database.

## Adding support to multi databases

We had only a MONGO_URI environment variable.
We decided to create one environment variable for each other database we are going to add. We are following the pattern `MONGO_URI_<>`.

After adding the new env, we need to create a connection to this database:

```jsx
// default connection
await mongoose.connect(config.MONGO_URI, options);

// other connections
await mongoose.createConnection(config.MONGO_URI_LOGS)
.asPromise();
```

Mongoose has a concept of connections, and it has a default connection. The default connection will be used for all models and schemas that you define.
The other connections need to be explicitly used.

## Working with different databases

First, we need to define our collection schema:

```jsx
export const LogSchema = new mongoose.Schema(
  {
    metadata: {
      type: mongoose.SchemaTypes.Mixed,
    },
  },
  {
    collection: 'Log',
    timestamps: true,
  },
);

LogSchema.name = 'Log';
LogSchema.databaseName = 'woovi-log';

const LogModel: Model<ILog> = mongoose.model('Log', LogSchema);

export default LogModel;
```

In the code above, we define the `LogSchema`, and the `LogModel`.
The `LogModel` is the LogSchema in the context of the default connection
To query Log collection from the default connection, we would do:

```jsx
const logs = await LogModel.find();
```

To query logs from the `woovi-logs` database, we need a bit more work

```jsx
const Log = getModelBySchema(LogSchema);

const logs = await Log.find();
```

We first need to create a model from the schema.
Let's see how `getModelBySchema` is implemented:

```jsx
export const getConnection = (connectionName: string) => {
  const connection = mongoose.connections.find(
    (c) => c.name === connectionName,
  );

  if (!connection) {
    return mongoose;
  }

  return connection;
};

export const getModelBySchema = (schema) => {
  const connection = getConnection(schema.databaseName);

  return connection.model(schema.name, schema);
};
```

We first get the connection by name from `mongoose.connections` array, then we call `connection.model` to create a model from the schema.


## To Conclude
As you scale you are going to need to break your database into more databases.
Creating the right abstraction can make this simple.

How many databases do you have in your product?

---
Woovi
[Woovi](https://www.woovi.com) is a Startup that enables shoppers to pay as they like. Woovi provides instant payment solutions for merchants to accept orders to make this possible.

If you want to work with us, we are [hiring](https://woovi.com/jobs/)!

---
<a href="https://www.freepik.com/free-ai-image/server-room-with-green-lights-indicating-energyefficient-operations_77714491.htm#fromView=search&term=databases&track=ais_ai_generated&regularType=ai&page=1&position=22&uuid=200acc6d-2bb5-436d-9c77-fb40d9fc07a8">Image By rorozoa</a>