or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

change-streams.mdcollection-crud.mdconnection-management.mddatabase-operations.mdencryption.mdgridfs.mdindex-management.mdindex.mdquery-aggregation.mdsessions-transactions.md

index-management.mddocs/

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

```