0
# Index Management
1
2
Index creation, management, and Atlas Search index operations for optimizing query performance, ensuring efficient data access patterns, and enabling full-text search capabilities.
3
4
## Capabilities
5
6
### Standard Index Operations
7
8
Core index management operations for creating, listing, and managing database indexes.
9
10
```java { .api }
11
/**
12
* Creates a single index on the collection
13
* @param keys the index specification as Bson
14
* @return the name of the created index
15
*/
16
String createIndex(Bson keys);
17
18
/**
19
* Creates a single index with options
20
* @param keys the index specification as Bson
21
* @param indexOptions options for index creation
22
* @return the name of the created index
23
*/
24
String createIndex(Bson keys, IndexOptions indexOptions);
25
26
/**
27
* Creates a single index with session support
28
* @param clientSession the session to use for the operation
29
* @param keys the index specification as Bson
30
* @return the name of the created index
31
*/
32
String createIndex(ClientSession clientSession, Bson keys);
33
34
/**
35
* Creates a single index with session and options
36
* @param clientSession the session to use for the operation
37
* @param keys the index specification as Bson
38
* @param indexOptions options for index creation
39
* @return the name of the created index
40
*/
41
String createIndex(ClientSession clientSession, Bson keys, IndexOptions indexOptions);
42
43
/**
44
* Creates multiple indexes in a single operation
45
* @param indexes list of IndexModel objects defining the indexes
46
* @return list of created index names
47
*/
48
List<String> createIndexes(List<IndexModel> indexes);
49
50
/**
51
* Creates multiple indexes with options
52
* @param indexes list of IndexModel objects defining the indexes
53
* @param createIndexOptions options for the create indexes operation
54
* @return list of created index names
55
*/
56
List<String> createIndexes(List<IndexModel> indexes, CreateIndexOptions createIndexOptions);
57
58
/**
59
* Creates multiple indexes with session support
60
* @param clientSession the session to use for the operation
61
* @param indexes list of IndexModel objects defining the indexes
62
* @return list of created index names
63
*/
64
List<String> createIndexes(ClientSession clientSession, List<IndexModel> indexes);
65
66
/**
67
* Drops an index by name
68
* @param indexName the name of the index to drop
69
*/
70
void dropIndex(String indexName);
71
72
/**
73
* Drops an index by keys specification
74
* @param keys the index specification as Bson
75
*/
76
void dropIndex(Bson keys);
77
78
/**
79
* Drops an index with session support
80
* @param clientSession the session to use for the operation
81
* @param indexName the name of the index to drop
82
*/
83
void dropIndex(ClientSession clientSession, String indexName);
84
85
/**
86
* Drops all indexes on the collection except the default _id index
87
*/
88
void dropIndexes();
89
90
/**
91
* Drops all indexes with session support
92
* @param clientSession the session to use for the operation
93
*/
94
void dropIndexes(ClientSession clientSession);
95
96
/**
97
* Lists all indexes on the collection
98
* @return ListIndexesIterable for iterating over index information
99
*/
100
ListIndexesIterable<Document> listIndexes();
101
102
/**
103
* Lists all indexes returning custom type
104
* @param clazz the class to decode each index document to
105
* @return ListIndexesIterable for iterating over index information
106
*/
107
<TResult> ListIndexesIterable<TResult> listIndexes(Class<TResult> clazz);
108
109
/**
110
* Lists all indexes with session support
111
* @param clientSession the session to use for the operation
112
* @return ListIndexesIterable for iterating over index information
113
*/
114
ListIndexesIterable<Document> listIndexes(ClientSession clientSession);
115
```
116
117
**Usage Examples:**
118
119
```java
120
import com.mongodb.client.model.Indexes;
121
import com.mongodb.client.model.IndexOptions;
122
import com.mongodb.client.model.IndexModel;
123
import java.util.concurrent.TimeUnit;
124
125
// Create simple ascending index
126
String indexName = collection.createIndex(Indexes.ascending("username"));
127
System.out.println("Created index: " + indexName);
128
129
// Create compound index
130
collection.createIndex(Indexes.compound(
131
Indexes.ascending("category"),
132
Indexes.descending("price"),
133
Indexes.ascending("name")
134
));
135
136
// Create index with options
137
IndexOptions options = new IndexOptions()
138
.unique(true)
139
.background(true)
140
.name("unique_email_idx")
141
.expireAfter(30, TimeUnit.DAYS);
142
143
collection.createIndex(Indexes.ascending("email"), options);
144
145
// Create multiple indexes efficiently
146
List<IndexModel> indexes = Arrays.asList(
147
new IndexModel(Indexes.ascending("userId")),
148
new IndexModel(Indexes.ascending("timestamp")),
149
new IndexModel(Indexes.compound(
150
Indexes.ascending("userId"),
151
Indexes.descending("timestamp")
152
), new IndexOptions().name("user_timeline_idx"))
153
);
154
155
List<String> createdIndexes = collection.createIndexes(indexes);
156
System.out.println("Created indexes: " + createdIndexes);
157
158
// List all indexes
159
for (Document index : collection.listIndexes()) {
160
System.out.println("Index: " + index.toJson());
161
}
162
163
// Drop specific index
164
collection.dropIndex("unique_email_idx");
165
166
// Drop index by specification
167
collection.dropIndex(Indexes.ascending("username"));
168
```
169
170
### Index Types and Specifications
171
172
Various index types supported by MongoDB for different use cases.
173
174
```java { .api }
175
// Single field indexes
176
Bson ascendingIndex = Indexes.ascending("fieldName");
177
Bson descendingIndex = Indexes.descending("fieldName");
178
179
// Compound indexes
180
Bson compoundIndex = Indexes.compound(
181
Indexes.ascending("field1"),
182
Indexes.descending("field2"),
183
Indexes.ascending("field3")
184
);
185
186
// Text indexes for full-text search
187
Bson textIndex = Indexes.text("title");
188
Bson multiFieldTextIndex = Indexes.compoundIndex(
189
Indexes.text("title"),
190
Indexes.text("content"),
191
Indexes.text("tags")
192
);
193
194
// Geospatial indexes
195
Bson geo2dIndex = Indexes.geo2d("location");
196
Bson geo2dsphereIndex = Indexes.geo2dsphere("coordinates");
197
198
// Hashed indexes for sharding
199
Bson hashedIndex = Indexes.hashed("shardKey");
200
201
// Wildcard indexes for dynamic schemas
202
Bson wildcardIndex = Indexes.text("$**");
203
Bson fieldWildcardIndex = Indexes.text("metadata.$**");
204
```
205
206
**Usage Examples:**
207
208
```java
209
// Create text index for search functionality
210
collection.createIndex(Indexes.compoundIndex(
211
Indexes.text("title"),
212
Indexes.text("content"),
213
Indexes.text("tags")
214
), new IndexOptions().name("content_search_idx"));
215
216
// Create geospatial index for location-based queries
217
collection.createIndex(Indexes.geo2dsphere("location"));
218
219
// Query using geospatial index
220
List<Document> nearbyPlaces = collection.find(
221
Filters.near("location", -73.9857, 40.7484, 1000.0, 0.0)
222
).into(new ArrayList<>());
223
224
// Create partial index for efficient sparse data
225
IndexOptions partialOptions = new IndexOptions()
226
.partialFilterExpression(Filters.exists("premiumUser", true))
227
.name("premium_users_idx");
228
229
collection.createIndex(Indexes.ascending("userId"), partialOptions);
230
231
// Create TTL index for automatic document expiration
232
IndexOptions ttlOptions = new IndexOptions()
233
.expireAfter(7, TimeUnit.DAYS)
234
.name("session_ttl_idx");
235
236
collection.createIndex(Indexes.ascending("createdAt"), ttlOptions);
237
```
238
239
### Advanced Index Options
240
241
Comprehensive index configuration options for performance optimization and specialized use cases.
242
243
```java { .api }
244
/**
245
* IndexOptions for configuring index creation
246
*/
247
public class IndexOptions {
248
/**
249
* Sets whether the index should enforce uniqueness
250
* @param unique true for unique index
251
* @return IndexOptions with unique setting
252
*/
253
public IndexOptions unique(boolean unique);
254
255
/**
256
* Sets whether the index should be built in the background
257
* @param background true for background index build
258
* @return IndexOptions with background setting
259
*/
260
public IndexOptions background(boolean background);
261
262
/**
263
* Sets whether the index should be sparse (skip null values)
264
* @param sparse true for sparse index
265
* @return IndexOptions with sparse setting
266
*/
267
public IndexOptions sparse(boolean sparse);
268
269
/**
270
* Sets the name of the index
271
* @param name the index name
272
* @return IndexOptions with specified name
273
*/
274
public IndexOptions name(String name);
275
276
/**
277
* Sets the partial filter expression for partial indexes
278
* @param partialFilterExpression the filter expression
279
* @return IndexOptions with partial filter
280
*/
281
public IndexOptions partialFilterExpression(Bson partialFilterExpression);
282
283
/**
284
* Sets the TTL (time to live) for documents
285
* @param expireAfter the time after which documents expire
286
* @param timeUnit the time unit
287
* @return IndexOptions with TTL setting
288
*/
289
public IndexOptions expireAfter(Long expireAfter, TimeUnit timeUnit);
290
291
/**
292
* Sets the collation for string comparisons in the index
293
* @param collation the collation specification
294
* @return IndexOptions with collation
295
*/
296
public IndexOptions collation(Collation collation);
297
298
/**
299
* Sets wildcard projection for wildcard indexes
300
* @param wildcardProjection the projection specification
301
* @return IndexOptions with wildcard projection
302
*/
303
public IndexOptions wildcardProjection(Bson wildcardProjection);
304
305
/**
306
* Sets storage engine options
307
* @param storageEngine storage engine specific options
308
* @return IndexOptions with storage engine settings
309
*/
310
public IndexOptions storageEngine(Bson storageEngine);
311
}
312
```
313
314
**Usage Examples:**
315
316
```java
317
// Unique index with custom name and collation
318
Collation caseInsensitive = Collation.builder()
319
.locale("en")
320
.caseLevel(false)
321
.build();
322
323
IndexOptions uniqueOptions = new IndexOptions()
324
.unique(true)
325
.name("unique_username_ci")
326
.collation(caseInsensitive);
327
328
collection.createIndex(Indexes.ascending("username"), uniqueOptions);
329
330
// Partial index for active users only
331
IndexOptions activeUserOptions = new IndexOptions()
332
.partialFilterExpression(Filters.eq("status", "active"))
333
.name("active_users_email_idx");
334
335
collection.createIndex(Indexes.ascending("email"), activeUserOptions);
336
337
// Sparse index for optional fields
338
IndexOptions sparseOptions = new IndexOptions()
339
.sparse(true)
340
.name("optional_phone_idx");
341
342
collection.createIndex(Indexes.ascending("phoneNumber"), sparseOptions);
343
344
// Wildcard index with projection
345
IndexOptions wildcardOptions = new IndexOptions()
346
.wildcardProjection(new Document()
347
.append("metadata.tags", 1)
348
.append("metadata.category", 1)
349
.append("metadata.priority", 0)) // Exclude priority
350
.name("metadata_wildcard_idx");
351
352
collection.createIndex(Indexes.text("metadata.$**"), wildcardOptions);
353
```
354
355
### Atlas Search Index Operations
356
357
Operations for managing Atlas Search indexes for full-text search capabilities.
358
359
```java { .api }
360
/**
361
* Creates an Atlas Search index
362
* @param indexName the name of the search index
363
* @param definition the search index definition as Bson
364
* @return the name of the created search index
365
*/
366
String createSearchIndex(String indexName, Bson definition);
367
368
/**
369
* Creates an Atlas Search index with default name
370
* @param definition the search index definition as Bson
371
* @return the name of the created search index
372
*/
373
String createSearchIndex(Bson definition);
374
375
/**
376
* Creates multiple Atlas Search indexes
377
* @param searchIndexes list of SearchIndexModel objects
378
* @return list of created search index names
379
*/
380
List<String> createSearchIndexes(List<SearchIndexModel> searchIndexes);
381
382
/**
383
* Updates an Atlas Search index
384
* @param indexName the name of the search index to update
385
* @param definition the new search index definition
386
*/
387
void updateSearchIndex(String indexName, Bson definition);
388
389
/**
390
* Drops an Atlas Search index
391
* @param indexName the name of the search index to drop
392
*/
393
void dropSearchIndex(String indexName);
394
395
/**
396
* Lists Atlas Search indexes
397
* @return ListSearchIndexesIterable for iterating over search indexes
398
*/
399
ListSearchIndexesIterable<Document> listSearchIndexes();
400
401
/**
402
* Lists Atlas Search indexes with a specific name
403
* @param indexName the name of the search indexes to list
404
* @return ListSearchIndexesIterable for iterating over search indexes
405
*/
406
ListSearchIndexesIterable<Document> listSearchIndexes(String indexName);
407
```
408
409
**Usage Examples:**
410
411
```java
412
// Create basic Atlas Search index
413
Document searchIndexDefinition = new Document()
414
.append("mappings", new Document()
415
.append("dynamic", true)
416
.append("fields", new Document()
417
.append("title", new Document()
418
.append("type", "string")
419
.append("analyzer", "lucene.standard"))
420
.append("content", new Document()
421
.append("type", "string")
422
.append("analyzer", "lucene.english"))
423
.append("tags", new Document()
424
.append("type", "stringFacet"))));
425
426
String searchIndexName = collection.createSearchIndex("content_search", searchIndexDefinition);
427
System.out.println("Created search index: " + searchIndexName);
428
429
// Create search index with autocomplete
430
Document autocompleteDefinition = new Document()
431
.append("mappings", new Document()
432
.append("fields", new Document()
433
.append("title", new Document()
434
.append("type", "autocomplete")
435
.append("analyzer", "lucene.standard")
436
.append("tokenization", "edgeGram")
437
.append("minGrams", 2)
438
.append("maxGrams", 10))));
439
440
collection.createSearchIndex("autocomplete_idx", autocompleteDefinition);
441
442
// Create vector search index for semantic search
443
Document vectorDefinition = new Document()
444
.append("fields", new Document()
445
.append("embedding", new Document()
446
.append("type", "vector")
447
.append("dimensions", 768)
448
.append("similarity", "cosine")));
449
450
collection.createSearchIndex("vector_search", vectorDefinition);
451
452
// List all search indexes
453
for (Document searchIndex : collection.listSearchIndexes()) {
454
System.out.println("Search Index: " + searchIndex.toJson());
455
}
456
457
// Update search index
458
Document updatedDefinition = new Document()
459
.append("mappings", new Document()
460
.append("dynamic", false)
461
.append("fields", new Document()
462
.append("title", new Document()
463
.append("type", "string")
464
.append("analyzer", "lucene.keyword"))
465
.append("description", new Document()
466
.append("type", "string")
467
.append("analyzer", "lucene.english"))));
468
469
collection.updateSearchIndex("content_search", updatedDefinition);
470
```
471
472
### ListIndexesIterable Interface
473
474
Interface for querying and filtering index information.
475
476
```java { .api }
477
/**
478
* Interface for listing indexes with configuration options
479
*/
480
public interface ListIndexesIterable<TResult> extends MongoIterable<TResult> {
481
/**
482
* Sets the maximum execution time
483
* @param maxTime the maximum time
484
* @param timeUnit the time unit
485
* @return ListIndexesIterable with time limit
486
*/
487
ListIndexesIterable<TResult> maxTime(long maxTime, TimeUnit timeUnit);
488
489
/**
490
* Sets the batch size for cursor operations
491
* @param batchSize the batch size
492
* @return ListIndexesIterable with specified batch size
493
*/
494
ListIndexesIterable<TResult> batchSize(int batchSize);
495
496
/**
497
* Adds a comment to the list indexes operation
498
* @param comment the comment string
499
* @return ListIndexesIterable with comment
500
*/
501
ListIndexesIterable<TResult> comment(String comment);
502
}
503
```
504
505
### Index Performance Monitoring
506
507
Tools and techniques for monitoring and optimizing index performance.
508
509
```java { .api }
510
// Analyze index usage statistics
511
Document indexStats = database.runCommand(new Document("collStats", "myCollection")
512
.append("indexDetails", true));
513
514
System.out.println("Index statistics: " + indexStats.toJson());
515
516
// Get index usage statistics
517
Document indexUsage = database.runCommand(new Document("aggregate", "myCollection")
518
.append("pipeline", Arrays.asList(
519
new Document("$indexStats", new Document())
520
)));
521
522
// Explain query to verify index usage
523
Document explainResult = collection.find(Filters.eq("userId", 12345))
524
.explain(ExplainVerbosity.EXECUTION_STATS);
525
526
System.out.println("Query execution plan: " + explainResult.toJson());
527
528
// Monitor slow queries and missing indexes
529
MongoCollection<Document> profilerCollection = database.getCollection("system.profile");
530
531
// Enable profiling for slow operations
532
database.runCommand(new Document("profile", 2)
533
.append("slowms", 100)
534
.append("sampleRate", 1.0));
535
536
// Query profiler data for operations without index usage
537
List<Document> slowQueries = profilerCollection.find(
538
Filters.and(
539
Filters.gte("ts", Date.from(Instant.now().minus(1, ChronoUnit.HOURS))),
540
Filters.eq("planSummary", "COLLSCAN")
541
)
542
).into(new ArrayList<>());
543
544
for (Document slowQuery : slowQueries) {
545
System.out.println("Slow query without index: " + slowQuery.toJson());
546
}
547
```
548
549
### Index Maintenance and Best Practices
550
551
Guidelines for maintaining optimal index performance and managing index lifecycle.
552
553
```java { .api }
554
// Regular index maintenance
555
private void performIndexMaintenance() {
556
// Rebuild fragmented indexes (MongoDB handles this automatically in most cases)
557
558
// Remove unused indexes
559
removeUnusedIndexes();
560
561
// Update index statistics
562
database.runCommand(new Document("planCacheClear", collection.getNamespace().getCollectionName()));
563
564
// Monitor index size and performance
565
monitorIndexPerformance();
566
}
567
568
private void removeUnusedIndexes() {
569
// Get index usage statistics
570
List<Document> indexStats = collection.aggregate(Arrays.asList(
571
new Document("$indexStats", new Document())
572
)).into(new ArrayList<>());
573
574
Date thirtyDaysAgo = Date.from(Instant.now().minus(30, ChronoUnit.DAYS));
575
576
for (Document indexStat : indexStats) {
577
String indexName = indexStat.getString("name");
578
Document accesses = indexStat.get("accesses", Document.class);
579
580
if (!indexName.equals("_id_") && accesses.getInteger("ops", 0) == 0) {
581
Date lastAccess = accesses.getDate("since");
582
if (lastAccess.before(thirtyDaysAgo)) {
583
System.out.println("Considering removal of unused index: " + indexName);
584
// collection.dropIndex(indexName); // Uncomment to actually drop
585
}
586
}
587
}
588
}
589
590
// Index creation strategy for large collections
591
private void createIndexesForLargeCollection() {
592
// Create indexes during low-traffic periods
593
CreateIndexOptions options = new CreateIndexOptions()
594
.background(true) // Note: background option is deprecated in MongoDB 4.2+
595
.maxTime(2, TimeUnit.HOURS);
596
597
List<IndexModel> indexes = Arrays.asList(
598
new IndexModel(Indexes.ascending("frequently_queried_field")),
599
new IndexModel(Indexes.compound(
600
Indexes.ascending("user_id"),
601
Indexes.descending("timestamp")
602
))
603
);
604
605
try {
606
List<String> created = collection.createIndexes(indexes, options);
607
System.out.println("Successfully created indexes: " + created);
608
} catch (MongoException e) {
609
System.err.println("Index creation failed: " + e.getMessage());
610
// Handle index creation failure
611
}
612
}
613
614
// Index optimization for different query patterns
615
private void optimizeIndexesForQueryPatterns() {
616
// For equality queries: single field ascending index
617
collection.createIndex(Indexes.ascending("status"));
618
619
// For range queries: single field index (ascending/descending based on sort)
620
collection.createIndex(Indexes.descending("createdAt"));
621
622
// For sorting: compound index with sort fields last
623
collection.createIndex(Indexes.compound(
624
Indexes.ascending("category"), // Filter field first
625
Indexes.descending("priority"), // Sort field second
626
Indexes.descending("createdAt") // Additional sort field
627
));
628
629
// For text search: text index with weights
630
collection.createIndex(Indexes.compoundIndex(
631
Indexes.text("title"),
632
Indexes.text("content")
633
), new IndexOptions()
634
.weights(new Document("title", 10).append("content", 1))
635
.name("weighted_text_search"));
636
}
637
```