Skip to content

Commit e4504f6

Browse files
authored
Merge pull request #22 from mongodb/java-clean-up
fix(java): index creation logic
2 parents c55950b + 54eab01 commit e4504f6

2 files changed

Lines changed: 106 additions & 43 deletions

File tree

mflix/README-JAVA-SPRING.md

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ This is a full-stack movie browsing application built with Java Spring Boot and
1818

1919
- **Java 21** or higher
2020
- **Node.js 20** or higher
21-
- **MongoDB Atlas account** with the `sample_mflix` dataset loaded
22-
- [Load sample data](https://www.mongodb.com/docs/atlas/sample-data/) in your Atlas cluster
21+
- **MongoDB Atlas cluster or local deployment** with the `sample_mflix` dataset loaded
22+
- [Load sample data](https://www.mongodb.com/docs/atlas/sample-data/)
2323
- **Maven** (included via Maven Wrapper)
2424

2525
## Getting Started
@@ -130,12 +130,40 @@ The Next.js frontend uses:
130130
- **Next.js 16** with App Router
131131
- **Turbopack** for fast development builds
132132

133-
To build for production:
133+
#### Development Mode
134+
135+
For active development with hot reloading and fast refresh:
136+
137+
```bash
138+
cd client
139+
npm run dev
140+
```
141+
142+
This starts the development server on `http://localhost:3000` with Turbopack for fast rebuilds.
143+
144+
#### Production Build
145+
146+
To create an optimized production build and run it:
147+
148+
```bash
149+
cd client
150+
npm run build # Creates optimized production build
151+
npm start # Starts production server
152+
```
153+
154+
The production build:
155+
- Minifies and optimizes JavaScript and CSS
156+
- Optimizes images and assets
157+
- Generates static pages where possible
158+
- Provides better performance for end users
159+
160+
#### Linting
161+
162+
To check code quality:
134163

135164
```bash
136165
cd client
137-
npm run build
138-
npm start
166+
npm run lint
139167
```
140168

141169
## Issues

server/java-spring/src/main/java/com/mongodb/samplemflix/config/DatabaseVerification.java

Lines changed: 73 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -132,32 +132,43 @@ private void verifyMoviesCollection() {
132132
* these fields, which is used by the search endpoint in the API.
133133
*
134134
* <p>The index is created in the background to avoid blocking other operations.
135-
* If the index already exists, MongoDB will ignore the duplicate creation request.
135+
* If the index already exists, this method will detect it and skip creation.
136136
*
137137
* @param moviesCollection the movies collection to create the index on
138138
*/
139139
private void createTextSearchIndex(MongoCollection<Document> moviesCollection) {
140140
try {
141-
// Create compound text index on plot, title, and fullplot fields
142-
// The background option allows the index to be built without blocking other operations
143-
IndexOptions indexOptions = new IndexOptions()
144-
.name(TEXT_INDEX_NAME)
145-
.background(true);
146-
147-
// Create the text index using field name constants from Movie.Fields
148-
// This makes the coupling between Movie class and index creation explicit
149-
// and allows IDE "Find Usages" to track dependencies
150-
// MongoDB will automatically ignore this if the index already exists
151-
moviesCollection.createIndex(
152-
Indexes.compoundIndex(
153-
Indexes.text(Movie.Fields.PLOT),
154-
Indexes.text(Movie.Fields.TITLE),
155-
Indexes.text(Movie.Fields.FULLPLOT)
156-
),
157-
indexOptions
158-
);
141+
// Check if the text search index already exists
142+
boolean indexExists = false;
143+
for (Document index : moviesCollection.listIndexes()) {
144+
if (TEXT_INDEX_NAME.equals(index.getString("name"))) {
145+
indexExists = true;
146+
logger.info("Text search index '{}' already exists", TEXT_INDEX_NAME);
147+
break;
148+
}
149+
}
159150

160-
logger.info("Text search index '{}' created/verified for movies collection", TEXT_INDEX_NAME);
151+
if (!indexExists) {
152+
// Create compound text index on plot, title, and fullplot fields
153+
// The background option allows the index to be built without blocking other operations
154+
IndexOptions indexOptions = new IndexOptions()
155+
.name(TEXT_INDEX_NAME)
156+
.background(true);
157+
158+
// Create the text index using field name constants from Movie.Fields
159+
// This makes the coupling between Movie class and index creation explicit
160+
// and allows IDE "Find Usages" to track dependencies
161+
moviesCollection.createIndex(
162+
Indexes.compoundIndex(
163+
Indexes.text(Movie.Fields.PLOT),
164+
Indexes.text(Movie.Fields.TITLE),
165+
Indexes.text(Movie.Fields.FULLPLOT)
166+
),
167+
indexOptions
168+
);
169+
170+
logger.info("Text search index '{}' created successfully for movies collection", TEXT_INDEX_NAME);
171+
}
161172

162173
} catch (Exception e) {
163174
// Log error but don't fail - the application can still function without the index
@@ -240,7 +251,7 @@ private void createMongoDBSearchIndex(MongoCollection<Document> moviesCollection
240251
}
241252

242253
/**
243-
* Creates an index on the year field for the movies collection.
254+
* Creates an index on the year field for the movies collection if it doesn't already exist.
244255
*
245256
* <p>This index improves performance for aggregation queries that filter by year,
246257
* such as the movies with comments aggregation.
@@ -249,16 +260,28 @@ private void createMongoDBSearchIndex(MongoCollection<Document> moviesCollection
249260
*/
250261
private void createYearIndex(MongoCollection<Document> moviesCollection) {
251262
try {
252-
IndexOptions indexOptions = new IndexOptions()
253-
.name(YEAR_INDEX_NAME)
254-
.background(true);
263+
// Check if the year index already exists
264+
boolean indexExists = false;
265+
for (Document index : moviesCollection.listIndexes()) {
266+
if (YEAR_INDEX_NAME.equals(index.getString("name"))) {
267+
indexExists = true;
268+
logger.info("Year index '{}' already exists", YEAR_INDEX_NAME);
269+
break;
270+
}
271+
}
255272

256-
moviesCollection.createIndex(
257-
Indexes.ascending(Movie.Fields.YEAR),
258-
indexOptions
259-
);
273+
if (!indexExists) {
274+
IndexOptions indexOptions = new IndexOptions()
275+
.name(YEAR_INDEX_NAME)
276+
.background(true);
277+
278+
moviesCollection.createIndex(
279+
Indexes.ascending(Movie.Fields.YEAR),
280+
indexOptions
281+
);
260282

261-
logger.info("Year index '{}' created/verified for movies collection", YEAR_INDEX_NAME);
283+
logger.info("Year index '{}' created successfully for movies collection", YEAR_INDEX_NAME);
284+
}
262285

263286
} catch (Exception e) {
264287
logger.error("Could not create year index: {}", e.getMessage());
@@ -291,7 +314,7 @@ private void verifyCommentsCollection() {
291314
}
292315

293316
/**
294-
* Creates an index on the movie_id field for the comments collection.
317+
* Creates an index on the movie_id field for the comments collection if it doesn't already exist.
295318
*
296319
* <p>This index is critical for $lookup performance when joining movies with comments.
297320
* Without this index, the $lookup operation will perform a collection scan for each movie,
@@ -301,16 +324,28 @@ private void verifyCommentsCollection() {
301324
*/
302325
private void createMovieIdIndex(MongoCollection<Document> commentsCollection) {
303326
try {
304-
IndexOptions indexOptions = new IndexOptions()
305-
.name(MOVIE_ID_INDEX_NAME)
306-
.background(true);
327+
// Check if the movie_id index already exists
328+
boolean indexExists = false;
329+
for (Document index : commentsCollection.listIndexes()) {
330+
if (MOVIE_ID_INDEX_NAME.equals(index.getString("name"))) {
331+
indexExists = true;
332+
logger.info("Movie ID index '{}' already exists", MOVIE_ID_INDEX_NAME);
333+
break;
334+
}
335+
}
307336

308-
commentsCollection.createIndex(
309-
Indexes.ascending("movie_id"),
310-
indexOptions
311-
);
337+
if (!indexExists) {
338+
IndexOptions indexOptions = new IndexOptions()
339+
.name(MOVIE_ID_INDEX_NAME)
340+
.background(true);
312341

313-
logger.info("Movie ID index '{}' created/verified for comments collection", MOVIE_ID_INDEX_NAME);
342+
commentsCollection.createIndex(
343+
Indexes.ascending("movie_id"),
344+
indexOptions
345+
);
346+
347+
logger.info("Movie ID index '{}' created successfully for comments collection", MOVIE_ID_INDEX_NAME);
348+
}
314349

315350
} catch (Exception e) {
316351
logger.error("Could not create movie_id index: {}", e.getMessage());

0 commit comments

Comments
 (0)