Cosmos DB’s MongoDB API lets you leverage the familiar MongoDB protocol and drivers while benefiting from Azure’s managed infrastructure and global distribution.
Here’s a peek at it in action. Imagine you have a Node.js application that needs to store user profiles.
const { MongoClient } = require('mongodb');
async function run() {
const uri = "mongodb://your-cosmosdb-account.mongo.cosmos.azure.com:10255/?ssl=true&replicaSet=globaldb&retrywrites=false&maxIdleTimeMS=120000&appName=@your-app-name@";
const client = new MongoClient(uri);
try {
await client.connect();
console.log("Connected successfully to Cosmos DB MongoDB API");
const database = client.db("users");
const collection = database.collection("profiles");
// Insert a document
const newUser = { name: "Alice", email: "alice@example.com", registered: new Date() };
const insertResult = await collection.insertOne(newUser);
console.log(`Inserted user with _id: ${insertResult.insertedId}`);
// Find a document
const user = await collection.findOne({ email: "alice@example.com" });
console.log("Found user:", user);
} finally {
await client.close();
}
}
run().catch(console.dir);
This code, using the standard MongoDB driver, connects to your Cosmos DB endpoint. The uri points to your Cosmos DB account, specifying the MongoDB port (10255), the replicaSet=globaldb for global distribution, and other connection options. It then interacts with a database named "users" and a collection named "profiles" just as it would with a self-hosted MongoDB instance.
The core problem Cosmos DB’s MongoDB API solves is the operational overhead of managing a MongoDB cluster. You get automatic scaling, high availability, and global replication without needing to provision, patch, or monitor replica sets and sharding yourself. It abstracts away the underlying infrastructure, presenting a familiar MongoDB interface.
Internally, Cosmos DB translates MongoDB wire protocol requests into its own distributed storage and compute engine. When you perform an operation like insertOne, the request is routed to the appropriate partition within Cosmos DB. This partitioning is based on a partition key you define for your collections. Cosmos DB handles the distribution of data and requests across these partitions automatically.
The key levers you control are:
- Throughput (RU/s): This dictates the read and write capacity of your database or collection. You can provision throughput at the database level (shared across collections) or at the collection level (dedicated). This is crucial for performance and cost management.
- Partitioning: Choosing the right partition key is paramount. A good partition key distributes requests and data evenly across partitions, preventing hot spots and ensuring efficient scaling. A poorly chosen key can lead to performance bottlenecks.
- Indexing: Just like in MongoDB, you can define indexes on fields to speed up query performance. Cosmos DB automatically creates an index on
_id, but you’ll want to add others based on your query patterns. - Replication: Cosmos DB’s
globaldbreplica set configuration allows you to have read-write regions and read-only regions across the globe. You can configure which regions are active for writes and how data is replicated.
When you create a collection in Cosmos DB’s MongoDB API, you don’t just specify a name; you also define its partition key and the provisioned throughput. For example, creating a collection named users with a partition key userId and 5000 RU/s might look like this via the Azure CLI:
az cosmosdb mongodb collection create --resource-group myResourceGroup --account-name myCosmosDBAccount --database-name users --name users --partition-key-path "/userId" --throughput 5000
This command tells Cosmos DB how to distribute the users collection’s data and how much request capacity it has.
Most people focus on throughput and partition keys for performance, but the maxIdleTimeMS in the connection string is surprisingly impactful for connection pooling and latency. While the MongoDB driver typically handles connection pooling, setting this too high can lead to stale connections being held open, increasing the chance of transient network issues causing connection drops. A value around 120000 (2 minutes) is a common default, but tuning this based on your application’s connection churn and observing connection-related errors can significantly improve stability.
The next step is often understanding how to optimize queries for a distributed, partitioned data store, especially when dealing with cross-partition queries.