Getting Started navigation (v0.114-0)

You are viewing the frozen documentation for v0.114-0. It is not updated and may not reflect the latest release.

View current version →

MongoDB Shell Quick Start

Get started with DocumentDB using the MongoDB shell (mongosh) for a familiar MongoDB-compatible experience.

Prerequisites

Setting up DocumentDB locally

Pull the latest documentdb-local image and start the container. DocumentDB Local listens on port 10260 by default. Always set the username and password on first run - the container falls back to well-known built-in defaults otherwise.

# Pull the latest DocumentDB Docker image
docker pull ghcr.io/documentdb/documentdb/documentdb-local:latest

# Tag the image for convenience
docker tag ghcr.io/documentdb/documentdb/documentdb-local:latest documentdb

# Run the container with your chosen username and password
docker run -dt -p 10260:10260 --name documentdb-container documentdb --username <YOUR_USERNAME> --password <YOUR_PASSWORD>

Note: Replace <YOUR_USERNAME> and <YOUR_PASSWORD> with your desired credentials. Always set them explicitly: if you omit them the container starts with the built-in default_user / Admin100, which are public and let anyone who can reach the published port authenticate as the admin user.

Port note: Port 10260 is used by default to avoid conflicts with other local database services. You can use port 27017 (the standard MongoDB port) or any other available port — update the port in the docker run command and your connection string accordingly.

Confirm the container is running:

docker ps

docker ps reports the container as Up before DocumentDB can accept connections, so wait for the ready banner before connecting:

until docker logs documentdb-container 2>&1 | grep -q "=== DocumentDB is ready ==="; do sleep 2; done

If this has not returned after a couple of minutes, the container probably exited during startup - interrupt it and check docker logs documentdb-container.

Connecting to DocumentDB

DocumentDB Local accepts TLS connections on the gateway port and requires authentication. The container generates a self-signed certificate on first start and reuses it thereafter, so the simplest local connection skips certificate validation with tlsAllowInvalidCertificates=true.

mongosh "mongodb://<YOUR_USERNAME>:<YOUR_PASSWORD>@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true"

For instructions on installing the generated certificate so you can validate it normally, see DocumentDB Local.

Basic Operations

Create a database and collection

// Switch to (or create) a database
use mydb

// Create a collection
db.createCollection("users")

Insert documents

// Insert a single document
db.users.insertOne({
  name: "John Doe",
  email: "john@example.com",
  created_at: new Date()
})

// Insert multiple documents
db.users.insertMany([
  { name: "Jane Smith", email: "jane@example.com" },
  { name: "Bob Johnson", email: "bob@example.com" }
])

Query documents

// Find all documents
db.users.find()

// Find with a filter
db.users.find({ name: "John Doe" })

// Find with a projection
db.users.find({}, { name: 1, email: 1, _id: 0 })

// Combine multiple operators
db.users.find({
  $and: [
    { created_at: { $gte: new Date("2026-01-01") } },
    { email: { $regex: "@example.com$" } }
  ]
})

Update documents

// Update a single document
db.users.updateOne(
  { name: "John Doe" },
  { $set: { status: "active" } }
)

// Update many documents
db.users.updateMany(
  { email: { $regex: "@example.com$" } },
  { $set: { domain: "example.com" } }
)

Delete documents

// Delete a single document
db.users.deleteOne({ name: "John Doe" })

// Delete many documents
db.users.deleteMany({ status: "inactive" })

Working with Indexes

DocumentDB supports many MongoDB-compatible index types, including single-field, compound, multi-key, partial, unique, text, geospatial, and vector indexes.

// Single field index
db.users.createIndex({ name: 1 })

// Compound index
db.users.createIndex({ name: 1, email: 1 })

// Unique index
db.users.createIndex({ email: 1 }, { unique: true })

// Text index
db.articles.createIndex({ content: "text" })

// Geospatial (2dsphere) index
db.places.createIndex({ location: "2dsphere" })

// Partial index
db.orders.createIndex(
  { orderDate: 1 },
  { partialFilterExpression: { status: "active" } }
)

Each index above is on a distinct set of keys, which matters: when you don't pass a name, the index name is generated from the keys, so { email: 1 } becomes email_1 whatever options you give it. Creating both a plain and a unique index on { email: 1 } therefore collides on that one generated name and fails with An existing index has the same name as the requested index. Pass an explicit name to at least one of them if you need both.

Note also that a unique index is not sparse unless you say so. Documents that lack the indexed field are all treated as sharing a single "missing" value, so the second such document violates uniqueness. Add sparse: true when the field is optional.

To create a vector index on an embedding field, use the cosmosSearchOptions index spec accepted by the DocumentDB gateway:

db.products.createIndex(
  { embedding: "cosmosSearch" },
  {
    name: "vectorIndex",
    cosmosSearchOptions: {
      kind: "vector-ivf",
      numLists: 100,
      similarity: "COS",
      dimensions: 3
    }
  }
)

dimensions must match the length of the vectors you store and query — a query vector of a different length is rejected. Three is used here only to keep the example short; a real embedding field is typically 384, 768, or 1536 wide, depending on the model.

Aggregation Pipelines

db.orders.aggregate([
  { $match: { status: "completed" } },
  { $group: {
      _id: "$customer",
      total: { $sum: "$amount" },
      count: { $sum: 1 }
  }},
  { $sort: { total: -1 } }
])

DocumentDB also supports stages such as $lookup, $unwind, $facet, $bucket, $bucketAuto, and many others. See the API Reference for the full list.

Vector Search

This queries the vectorIndex created above, so the query vector has the same three dimensions the index declares:

db.products.aggregate([
  {
    $search: {
      cosmosSearch: {
        vector: [0.1, 0.2, 0.3],
        path: "embedding",
        k: 10
      }
    }
  }
])

Geospatial Queries

db.places.find({
  location: {
    $near: {
      $geometry: { type: "Point", coordinates: [-73.9667, 40.78] },
      $maxDistance: 1000
    }
  }
})

Diagnostics and Administration

DocumentDB ships with a number of MongoDB-compatible administrative commands:

// Build info and server info
db.runCommand({ buildInfo: 1 })
db.runCommand({ hello: 1 })

// Database and collection statistics
db.stats()
db.users.stats()

// List databases (admin DB)
db.adminCommand({ listDatabases: 1 })

// Inspect or kill currently running operations
db.currentOp()
db.killOp(<opid>)

// Validate a collection
db.users.validate()

// Compact a collection
db.runCommand({ compact: "users" })

User and role management commands are also supported, with two caveats specific to roles: they must be run from the admin database, and they are gated behind a server setting that is off by default. Enable it once, as a Postgres superuser, before running the role examples:

ALTER SYSTEM SET documentdb.enableRoleCrud = on;
SELECT pg_reload_conf();

This is a PostgreSQL GUC, so it cannot be set from mongosh — use psql or your provider's parameter settings. updateRole is not implemented regardless of this setting.

// Users — can be created from any database
db.runCommand({ createUser: "alice", pwd: "secret", roles: [ { role: "readAnyDatabase", db: "admin" } ] })
db.runCommand({ usersInfo: 1 })

// Roles — must be run against admin
use admin
db.runCommand({ createRole: "appReader", privileges: [], roles: [ "readAnyDatabase" ] })
db.runCommand({ rolesInfo: 1 })

DocumentDB does not implement per-database roles. createUser takes role documents and accepts exactly two sets, both scoped to admin[{ role: "readAnyDatabase", db: "admin" }] for read-only access, or [{ role: "clusterAdmin", db: "admin" }, { role: "readWriteAnyDatabase", db: "admin" }] for read-write access. Anything else, including readWrite or a db other than admin, is rejected.

createRole draws on the same three built-in roles but takes their names as bare strings, not documents — roles: [ "readAnyDatabase" ]. Passing a document there fails with Invalid inherited from role name provided. As with createUser, readWriteAnyDatabase and clusterAdmin must be named together. createRole also requires a privileges field, even when empty.

Best Practices

  • Connection pooling: reuse a single mongosh connection per session.
  • Indexes: create indexes that match your most frequent query and sort patterns. Use db.collection.getIndexes() to inspect existing indexes.
  • Explain plans: prefix queries with .explain("executionStats") to inspect how DocumentDB plans and executes them.
  • TLS: in production, always provide the gateway certificate via --tlsCAFile rather than disabling validation.

Next Steps