Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
20 changes: 13 additions & 7 deletions mflix/README-JAVA-SPRING.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ This is a full-stack movie browsing application built with Java Spring Boot and
- **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)
- **Voyage AI API key** (For MongoDB Vector Search)
- [Get a Voyage AI API key](https://www.voyageai.com/)

## Getting Started

Expand Down Expand Up @@ -100,11 +102,15 @@ Open your browser and navigate to:

## Features

- **Browse Movies:** View a paginated list of movies from the sample_mflix dataset
- **Search:** Full-text search using MongoDB Search
- **Filter:** Filter movies by genre, year, rating, and more
- **Movie Details:** View detailed information about each movie
- **Aggregations:** Complex data aggregations and analytics
- **Browse Movies:** View a paginated list of movies from the
sample_mflix dataset
- **CRUD Operations:** Create, read, update and delete movies by using
the MongoDB Java driver
- **Search:** Search movies with filters by using MongoDB Search
- **Vector Search:** Search movie plots with similar search terms by
using MongoDB Vector Search
- **Aggregations:** View data aggregations and analytics built with
aggregation pipelines

## Development

Expand Down Expand Up @@ -176,5 +182,5 @@ If you have problems running the sample app, please check the following:
- [ ] Verify that you have no firewalls blocking access to the server or client ports.

If you have verified the above and still have issues, please
[open an issue](https://github.com/mongodb/docs-sample-apps/issues/new/choose)
on the source repository `mongodb/docs-sample-apps`.
[open an issue](https://github.com/mongodb/sample-app-java-mflix/issues/new/choose)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[open an issue](https://github.com/mongodb/sample-app-java-mflix/issues/new/choose)
[open an issue](https://github.com/mongodb/docs-sample-apps/issues/new/choose)

on the source repository `mongodb/sample-app-java-mflix`.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, this was actually correct. We have disabled Issues on the artifact repos and want people to create issues directly on the source repo so we only have one place to watch instead of three of them.

Suggested change
on the source repository `mongodb/sample-app-java-mflix`.
on the source repository `mongodb/docs-sample-apps`.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah good to know, I thought we were keeping the source repo separated. Changed back

196 changes: 189 additions & 7 deletions mflix/README-JAVASCRIPT-EXPRESS.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,198 @@
# JavaScript Express.js MongoDB Sample MFlix Application

[TODO: Add intro]
This is a full-stack movie browsing application built with Express.js and Next.js, demonstrating MongoDB operations using the `sample_mflix` dataset. The application showcases CRUD operations, aggregations, and MongoDB Search using the native MongoDB Node.js driver.

## Project Structure

```
├── README.md
├── client/ # Next.js frontend
└── server/ # Express.js backend
├── README-JAVASCRIPT-EXPRESS.md
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is the public-facing project, the README will be renamed by the copy tool to just README.md in the artifact repo.

Suggested change
├── README-JAVASCRIPT-EXPRESS.md
├── README.md

├── client/ # Next.js frontend (TypeScript)
└── server/js-express/ # Express.js backend
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, missed this - the copier tool will rename this to just server in the artifact repo.

Suggested change
└── server/js-express/ # Express.js backend
└── server/ # Express.js backend

├── src/
├── package.json
├── .env.example
└── tsconfig.json
```

## Prerequisites

- **Node.js 22** or higher
- **MongoDB Atlas cluster or local deployment** with the `sample_mflix` dataset loaded
- [Load sample data](https://www.mongodb.com/docs/atlas/sample-data/)
- **npm** (included with Node.js)
- **Voyage AI API key** (For MongoDB Vector Search)
- [Get a Voyage AI API key](https://www.voyageai.com/)

## Getting Started

[TODO: Add getting started instructions explaining how to set connection string, start server, start client, etc.]
### 1. Configure the Backend

Navigate to the Express server directory:

```bash
cd server/js-express
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cd server/js-express
cd server/

```

Create a `.env` file from the example:

```bash
cp .env.example .env
```

Edit the `.env` file and set your MongoDB connection string:

```env
# MongoDB Configuration
# Replace with your MongoDB Atlas connection string
MONGODB_URI=mongodb+srv://<username>:<password>@<cluster>.mongodb.net/sample_mflix?retryWrites=true&w=majority
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the Voyage API key to the Python and Java .env.example files when I moved them - we should probably do this for JS too and update this README to match.


# Server Configuration
PORT=3001
NODE_ENV=development

# CORS Configuration (frontend URL)
CORS_ORIGIN=http://localhost:3000

# Optional: Enable MongoDB Search tests
# Uncomment the following line to enable Search tests
# ENABLE_SEARCH_TESTS=true
```

**Note:** Replace `<username>`, `<password>`, and `<cluster>` with your actual MongoDB Atlas credentials.

### 2. Install Backend Dependencies

From the `server/js-express` directory, run:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
From the `server/js-express` directory, run:
From the `server/` directory, run:


```bash
npm install
```

### 3. Start the Backend Server

From the `server/js-express` directory, run:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
From the `server/js-express` directory, run:
From the `server/` directory, run:


```bash
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend making these separate bash blocks so users can just execute them in their IDE if they want to.

# Development mode with hot reloading
npm run dev

# Or production mode
npm run build
npm start
```

The server will start on `http://localhost:3001`. You can verify it's running by visiting:
- API root: http://localhost:3001/
- API documentation (Swagger UI): http://localhost:3001/api-docs

### 4. Configure and Start the Frontend

Open a new terminal and navigate to the client directory:

```bash
cd client
```

Install dependencies:

```bash
npm install
```

Start the development server:

```bash
npm run dev
```

The Next.js application will start on `http://localhost:3000`.

### 5. Access the Application

Open your browser and navigate to:
- **Frontend:** http://localhost:3000
- **Backend API:** http://localhost:3001
- **API Documentation:** http://localhost:3001/api-docs

## Features

- **Browse Movies:** View a paginated list of movies from the
sample_mflix dataset
- **CRUD Operations:** Create, read, update and delete movies by using
the MongoDB Node.js driver
- **Search:** Search movies with filters by using MongoDB Search
- **Vector Search:** Search movie plots with similar search terms by
using MongoDB Vector Search
- **Aggregations:** View data aggregations and analytics built with
aggregation pipelines

## Development

### Backend Development

The Express.js backend uses:
- **Express.js 5** for REST API
- **MongoDB Node.js Driver** for database operations
- **TypeScript** for type safety
- **Swagger** for API documentation
- **Jest** for testing

To run tests:

```bash
cd server/js-express
npm test
```

To run tests with coverage:

```bash
cd server/js-express
npm run test:coverage
```

### Frontend Development

The Next.js frontend uses:
- **React 19** with TypeScript
- **Next.js 16** with App Router
- **Turbopack** for fast development builds

#### 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 lint
```

## Issues

Expand All @@ -22,5 +204,5 @@ If you have problems running the sample app, please check the following:
- [ ] Verify that you have no firewalls blocking access to the server or client ports.

If you have verified the above and still have issues, please
[open an issue](https://github.com/mongodb/docs-sample-apps/issues/new/choose)
on the source repository `mongodb/docs-sample-apps`.
[open an issue](https://github.com/mongodb/sample-app-nodejs-mflix/issues/new/choose)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[open an issue](https://github.com/mongodb/sample-app-nodejs-mflix/issues/new/choose)
[open an issue](https://github.com/mongodb/docs-sample-apps/issues/new/choose)

on the source repository `mongodb/sample-app-nodejs-mflix`.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
on the source repository `mongodb/sample-app-nodejs-mflix`.
on the source repository `mongodb/docs-sample-apps`.

Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export interface SearchParams {
cast?: string;
limit?: number;
skip?: number;
search_operator?: 'must' | 'should' | 'mustNot' | 'filter';
searchOperator?: 'must' | 'should' | 'mustNot' | 'filter';
// Vector Search fields
q?: string;
}
Expand All @@ -42,7 +42,7 @@ interface SearchFormData {
writers: string;
cast: string;
limit: string;
search_operator: 'must' | 'should' | 'mustNot' | 'filter';
searchOperator: 'must' | 'should' | 'mustNot' | 'filter';
// Vector Search fields
q: string;
}
Expand All @@ -56,7 +56,7 @@ const getInitialFormData = (): SearchFormData => ({
writers: '',
cast: '',
limit: '20',
search_operator: 'must',
searchOperator: 'must',
// Vector Search fields
q: '',
});
Expand Down Expand Up @@ -115,7 +115,7 @@ export default function SearchMovieModal({

if (formData.searchType === 'mongodb-search') {
// Add MongoDB Search specific parameters
searchParams.search_operator = formData.search_operator;
searchParams.searchOperator = formData.searchOperator;
searchParams.skip = 0; // Always start from beginning for new search

if (formData.plot.trim()) {
Expand Down Expand Up @@ -316,13 +316,13 @@ export default function SearchMovieModal({

{/* Search Operator */}
<div className={styles.formGroup}>
<label htmlFor="search_operator" className={styles.label}>
<label htmlFor="searchOperator" className={styles.label}>
Search Logic
</label>
<select
id="search_operator"
value={formData.search_operator}
onChange={(e) => handleInputChange('search_operator', e.target.value)}
id="searchOperator"
value={formData.searchOperator}
onChange={(e) => handleInputChange('searchOperator', e.target.value)}
className={styles.input}
disabled={isLoading}
>
Expand All @@ -333,7 +333,7 @@ export default function SearchMovieModal({
))}
</select>
<small className={styles.searchOperatorDescription}>
{searchOperatorOptions.find(opt => opt.value === formData.search_operator)?.description}
{searchOperatorOptions.find(opt => opt.value === formData.searchOperator)?.description}
</small>
</div>
</>
Expand Down
4 changes: 2 additions & 2 deletions mflix/client/app/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ export async function searchMovies(searchParams: {
cast?: string;
limit?: number;
skip?: number;
search_operator?: 'must' | 'should' | 'mustNot' | 'filter';
searchOperator?: 'must' | 'should' | 'mustNot' | 'filter';
}): Promise<{ success: boolean; error?: string; movies?: Movie[]; hasNextPage?: boolean; hasPrevPage?: boolean; totalCount?: number }> {
try {
// Build query parameters
Expand All @@ -609,7 +609,7 @@ export async function searchMovies(searchParams: {
if (searchParams.cast) queryParams.append('cast', searchParams.cast);
queryParams.append('limit', limit.toString());
queryParams.append('skip', skip.toString());
if (searchParams.search_operator) queryParams.append('search_operator', searchParams.search_operator);
if (searchParams.searchOperator) queryParams.append('searchOperator', searchParams.searchOperator);

const response = await fetch(`${API_BASE_URL}/api/movies/search?${queryParams}`, {
method: 'GET',
Expand Down
5 changes: 4 additions & 1 deletion mflix/server/java-spring/.env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MongoDB Connection
# Replace with your MongoDB Atlas connection string or local MongoDB URI
MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/?retryWrites=true&w=majority
MONGODB_URI=mongodb+srv://<username>:<password>@<cluster>.mongodb.net/sample_mflix?retryWrites=true&w=majority

# Voyage AI Configuration
# API key for Voyage AI embedding model (required for Vector Search)
Expand All @@ -15,3 +15,6 @@ PORT=3001
# For multiple origins, separate with commas
CORS_ORIGIN=http://localhost:3000

# Optional: Enable MongoDB Search tests
# Uncomment the following line to enable Search tests
# ENABLE_SEARCH_TESTS=true
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public interface MovieService {

/**
* Finds similar movies using vector search on plot embeddings.
* Demonstrates MongoDB Atlas Vector Search.
* Demonstrates MongoDB Vector Search.
*
* @param movieId ID of the movie to find similar movies for
* @param limit Maximum number of similar movies to return (default: 10, max: 50)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ public List<Movie> findSimilarMovies(String movieId, Integer limit) {
.append("index", "plotEmbeddingIndex")
.append("path", "plot_embedding")
.append("queryVector", plotEmbedding)
.append("numCandidates", resultLimit * 10)
.append("numCandidates", resultLimit * 20) // We recommend searching 20 times higher than the limit to improve result relevance
.append("limit", resultLimit + 1) // +1 to exclude the source movie
);

Expand Down Expand Up @@ -847,7 +847,7 @@ public List<VectorSearchResult> vectorSearchMovies(String query, Integer limit)
.append("index", "vector_index")
.append("path", "plot_embedding_voyage_3_large")
.append("queryVector", queryVector)
.append("numCandidates", resultLimit * 15) // Search more candidates for better results
.append("numCandidates", resultLimit * 20) // We recommend searching 20 times higher than the limit to improve result relevance
.append("limit", resultLimit)
);

Expand Down
Loading