Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 33 additions & 5 deletions mflix/README-JAVA-SPRING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ This is a full-stack movie browsing application built with Java Spring Boot and

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

## Getting Started
Expand Down Expand Up @@ -130,12 +130,40 @@ The Next.js frontend uses:
- **Next.js 16** with App Router
- **Turbopack** for fast development builds

To build for production:
#### Development Mode

For active development with hot reloading and fast refresh:

```bash
cd client
npm run dev
```

This starts the development server on `http://localhost:3000` with Turbopack for fast rebuilds.

#### Production Build

To create an optimized production build and run it:

```bash
cd client
npm run build # Creates optimized production build
npm start # Starts production server
```

The production build:
- Minifies and optimizes JavaScript and CSS
- Optimizes images and assets
- Generates static pages where possible
- Provides better performance for end users

#### Linting

To check code quality:

```bash
cd client
npm run build
npm start
npm run lint
```

## Issues
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,32 +132,43 @@ private void verifyMoviesCollection() {
* these fields, which is used by the search endpoint in the API.
*
* <p>The index is created in the background to avoid blocking other operations.
* If the index already exists, MongoDB will ignore the duplicate creation request.
* If the index already exists, this method will detect it and skip creation.
*
* @param moviesCollection the movies collection to create the index on
*/
private void createTextSearchIndex(MongoCollection<Document> moviesCollection) {
try {
// Create compound text index on plot, title, and fullplot fields
// The background option allows the index to be built without blocking other operations
IndexOptions indexOptions = new IndexOptions()
.name(TEXT_INDEX_NAME)
.background(true);

// Create the text index using field name constants from Movie.Fields
// This makes the coupling between Movie class and index creation explicit
// and allows IDE "Find Usages" to track dependencies
// MongoDB will automatically ignore this if the index already exists
moviesCollection.createIndex(
Indexes.compoundIndex(
Indexes.text(Movie.Fields.PLOT),
Indexes.text(Movie.Fields.TITLE),
Indexes.text(Movie.Fields.FULLPLOT)
),
indexOptions
);
// Check if the text search index already exists
boolean indexExists = false;
for (Document index : moviesCollection.listIndexes()) {
if (TEXT_INDEX_NAME.equals(index.getString("name"))) {
indexExists = true;
logger.info("Text search index '{}' already exists", TEXT_INDEX_NAME);
break;
}
}

logger.info("Text search index '{}' created/verified for movies collection", TEXT_INDEX_NAME);
if (!indexExists) {
// Create compound text index on plot, title, and fullplot fields
// The background option allows the index to be built without blocking other operations
IndexOptions indexOptions = new IndexOptions()
.name(TEXT_INDEX_NAME)
.background(true);

// Create the text index using field name constants from Movie.Fields
// This makes the coupling between Movie class and index creation explicit
// and allows IDE "Find Usages" to track dependencies
moviesCollection.createIndex(
Indexes.compoundIndex(
Indexes.text(Movie.Fields.PLOT),
Indexes.text(Movie.Fields.TITLE),
Indexes.text(Movie.Fields.FULLPLOT)
),
indexOptions
);

logger.info("Text search index '{}' created successfully for movies collection", TEXT_INDEX_NAME);
}

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

/**
* Creates an index on the year field for the movies collection.
* Creates an index on the year field for the movies collection if it doesn't already exist.
*
* <p>This index improves performance for aggregation queries that filter by year,
* such as the movies with comments aggregation.
Expand All @@ -249,16 +260,28 @@ private void createMongoDBSearchIndex(MongoCollection<Document> moviesCollection
*/
private void createYearIndex(MongoCollection<Document> moviesCollection) {
try {
IndexOptions indexOptions = new IndexOptions()
.name(YEAR_INDEX_NAME)
.background(true);
// Check if the year index already exists
boolean indexExists = false;
for (Document index : moviesCollection.listIndexes()) {
if (YEAR_INDEX_NAME.equals(index.getString("name"))) {
indexExists = true;
logger.info("Year index '{}' already exists", YEAR_INDEX_NAME);
break;
}
}

moviesCollection.createIndex(
Indexes.ascending(Movie.Fields.YEAR),
indexOptions
);
if (!indexExists) {
IndexOptions indexOptions = new IndexOptions()
.name(YEAR_INDEX_NAME)
.background(true);

moviesCollection.createIndex(
Indexes.ascending(Movie.Fields.YEAR),
indexOptions
);

logger.info("Year index '{}' created/verified for movies collection", YEAR_INDEX_NAME);
logger.info("Year index '{}' created successfully for movies collection", YEAR_INDEX_NAME);
}

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

/**
* Creates an index on the movie_id field for the comments collection.
* Creates an index on the movie_id field for the comments collection if it doesn't already exist.
*
* <p>This index is critical for $lookup performance when joining movies with comments.
* Without this index, the $lookup operation will perform a collection scan for each movie,
Expand All @@ -301,16 +324,28 @@ private void verifyCommentsCollection() {
*/
private void createMovieIdIndex(MongoCollection<Document> commentsCollection) {
try {
IndexOptions indexOptions = new IndexOptions()
.name(MOVIE_ID_INDEX_NAME)
.background(true);
// Check if the movie_id index already exists
boolean indexExists = false;
for (Document index : commentsCollection.listIndexes()) {
if (MOVIE_ID_INDEX_NAME.equals(index.getString("name"))) {
indexExists = true;
logger.info("Movie ID index '{}' already exists", MOVIE_ID_INDEX_NAME);
break;
}
}

commentsCollection.createIndex(
Indexes.ascending("movie_id"),
indexOptions
);
if (!indexExists) {
IndexOptions indexOptions = new IndexOptions()
.name(MOVIE_ID_INDEX_NAME)
.background(true);

logger.info("Movie ID index '{}' created/verified for comments collection", MOVIE_ID_INDEX_NAME);
commentsCollection.createIndex(
Indexes.ascending("movie_id"),
indexOptions
);

logger.info("Movie ID index '{}' created successfully for comments collection", MOVIE_ID_INDEX_NAME);
}

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