A shard key is one or more document fields that MongoDB uses to partition a collection across shards. Shard-key values define nonoverlapping chunks: each chunk has an inclusive lower bound and an exclusive upper bound. Choosing the key matters because uneven distribution can overload a shard, while a key that poorly matches frequent queries can hurt query performance. section 9.3.3 section 9.3.8
Choose a key by checking both the data and the workload:
- Identify frequent reads and writes. A useful key supports common query patterns as well as distributing documents evenly. section 9.3.4
- Prefer many distinct, reasonably even values. A low-cardinality or heavily repeated value—such as a common status of “active”—can concentrate data and create a bottleneck. section 9.3.4
- Watch for steadily increasing or decreasing values. A timestamp used for ranged sharding can direct new inserts toward the same chunk, creating a write bottleneck. section 9.3.4
- Choose the distribution strategy deliberately. Ranged sharding groups nearby key values into ranges; hashed sharding spreads hashed values across ranges but is unsuitable for range-based queries. section 9.3.4
Assess a proposed key for flight routes
Suppose frequent route queries filter by source airport, destination airport, and airline name. In MongoDB 7.0 or later, enable query sampling on `sample_training.routes` with `db.routes.configureQueryAnalyzer({ mode: "full", samplesPerSecond: 1 })`. Create a supporting index with `db.routes.createIndex({ src_airport: 1, dst_airport: 1, "airline.name": 1 })`, then run representative queries to collect samples. Assess the proposed key with `db.routes.analyzeShardKey({ src_airport: 1, dst_airport: 1, "airline.name": 1 })`. Inspect characteristics such as distinct-value counts and common-value frequencies alongside the sampled query metrics before sharding the collection with `sh.shardCollection("sample_training.routes", { src_airport: 1, dst_airport: 1, "airline.name": 1 })`. section 9.3.5
Listing 9.13 Analyzing a proposed shard key
Atlas [mongos] sample_training> ➥db.routes.analyzeShardKey({ src_airport: 1, ➥dst_airport: 1,"airline.name": 1 }) { keyCharacteristics: { numDocsTotal: Long('66985'), avgDocSizeBytes: Long('184'), numDocsSampled: Long('66985'), isUnique: false, numDistinctValues: Long('66984'), mostCommonValues: [ { value: { src_airport: 'HAM', dst_airport: 'AMS', 'airline.name': 'Eurowings' }, frequency: Long('2') }, { value: { src_airport: 'KTM', dst_airport: 'DXB', 'airline.name': 'Fly Dubai' }, frequency: Long('1') }, { value: { src_airport: 'ADB', dst_airport: 'ARN', 'airline.name': 'SunExpress' }, frequency: Long('1') }, { value: { src_airport: 'FOC', dst_airport: 'TNA', 'airline.name': 'Air China' }, frequency: Long('1') }, { value: { src_airport: 'DTW', dst_airport: 'MEX', 'airline.name': 'AeroMéxico' }, frequency: Long('1') } ], monotonicity: { recordIdCorrelationCoefficient: 0.0163877874, type: 'not monotonic' } }, readDistribution: { sampleSize: { total: Long('525'), find: Long('525'), aggregate: Long('0'), count: Long('0'), distinct: Long('0') }, percentageOfSingleShardReads: 84.1904761905, percentageOfMultiShardReads: 12.1904761905, percentageOfScatterGatherReads: 3.6190476191, writeDistribution: { sampleSize: { total: Long('0'), update: Long('0'), delete: Long('0'), findAndModify: Long('0') } }, ok: 1, '$clusterTime': { clusterTime: Timestamp({ t: 1712596218, i: 99 }), signature: { hash: Binary.createFromBase64('E31gLvizNd2gwwpFIx9AESXDg8A=', 0), keyId: Long('7352622473289924630') } }, operationTime: Timestamp({ t: 1712596218, i: 99 }) } Atlas [mongos] sample_training>
The analyzer output shows whether the proposed compound key is unique, how many distinct values it has, and which values occur most often. section 9.3.5
A choice need not be permanent: MongoDB 4.4 and later can add suffix fields to an existing shard key, and MongoDB 5.0 and later can change a collection’s key through resharding. Resharding copies data into a new arrangement while the application continues to access and modify the collection. Plan for at least 1.2 times the collection size in available disk space, I/O use below 50%, and CPU use below 80% on each shard; these requirements are not enforced. During the operation, keep both old and new shard-key filters in relevant application queries, removing the old filters only after it completes. section 9.3.3 section 9.3.7
Chunk balancing can move shard-key ranges between shards to maintain an even distribution. It does not replace careful key selection: assess value distribution and query patterns before committing to a key, then account for balancing and resharding when planning changes. section 9.3.8 section 9.3.4
