End-to-end recommendation system combining modern Data Engineering, Machine Learning, and Generative AI.
MovieLens Recommendation System is an end-to-end data platform built on a modern Lakehouse architecture.
The project ingests the MovieLens dataset, transforms it with Apache Spark, stores curated data in Apache Iceberg, trains an ALS recommendation model, enriches movies with TMDb metadata, and enables semantic movie search through a Retrieval-Augmented Generation (RAG) pipeline powered by Ollama.
The entire workflow is orchestrated with Apache Airflow and exposed through a Streamlit web application.
Traditional recommender systems rely exclusively on collaborative filtering.
Although they are effective for personalization, they cannot answer natural language questions such as:
"I'm looking for a psychological thriller with unexpected plot twists."
This project combines:
- a scalable Data Lakehouse
- collaborative filtering
- semantic embeddings
- Retrieval-Augmented Generation (RAG)
to deliver both personalized recommendations and intelligent semantic search.
- End-to-end Data Lakehouse
- Apache Spark distributed processing
- Apache Iceberg tables
- Airflow orchestration
- ALS Collaborative Filtering
- Time-decay weighting
- Fairness-aware recommendations
- TMDb metadata enrichment
- Semantic Search
- PostgreSQL + pgvector
- Local embeddings with Ollama
- Interactive Streamlit frontend
The project is divided into two main pipelines: the Lakehouse Pipeline (Silver & Gold) and the AI Pipeline (RAG & Vector Database).
Fully orchestrated through decoupled Airflow DAGs.
Silver Layer (ETL & Data Cleaning):
- PySpark jobs process raw movie, rating, tag, and link datasets.
- Data is cleaned, properly typed, and stored as Apache Iceberg tables in a local S3 bucket powered by MinIO.
- Orchestration: all Spark jobs run inside a dedicated Airflow Pool (
spark_pool) to optimize resource utilization.
Gold Layer (Machine Learning - Advanced ALS):
- Training of a Collaborative Filtering model using Alternating Least Squares (ALS).
- Freshness (Time Decay): older ratings receive exponentially decreasing weights, allowing the model to prioritize recent user preferences.
- Fairness (Diversity): a logarithmic penalty is applied to blockbuster movies, increasing the visibility of highly rated long-tail titles.
- Final recommendations are stored in Iceberg using a flattened schema optimized for low-latency reads.
To allow users to "chat" with the movie catalog, the project includes a Retrieval-Augmented Generation (RAG) pipeline.
- Data Enrichment (TMDb API): a PySpark job reads the links dataset and retrieves movie plots, posters, and budget information from The Movie Database (TMDb), enriching the Iceberg tables in a distributed fashion.
- Embedding Generation (Ollama): movie titles, genres, and plot summaries are combined and embedded using the locally hosted
nomic-embed-textmodel running on Ollama. - Vector Database (PostgreSQL + pgvector): embeddings are stored in PostgreSQL (shared with Airflow) using the
pgvectorextension, enabling millisecond-scale cosine similarity searches. - Frontend (Streamlit): a lightweight web application divided into two tabs:
- Recommendations: retrieves recommendations from the Silver and Gold Iceberg tables using cached PySpark queries.
- AI Search: embeds the user's query with Ollama and searches PostgreSQL for semantically similar movies instead of relying on keyword matching.
- Data Processing: Apache Spark (PySpark)
- Storage: Apache Iceberg & MinIO (S3)
- Orchestration: Apache Airflow (Docker, SparkSubmitOperator, DockerOperator)
- Machine Learning (ALS): Spark MLlib
- Artificial Intelligence (RAG): Ollama (Local LLM) & PostgreSQL (pgvector)
- Frontend: Streamlit
- Package Manager: uv
Make sure you have the following installed:
- Docker & Docker Compose
- Python 3.10+
- uv (Python package and dependency manager)
- Ollama (installed with the
nomic-embed-textmodel running) - A TMDb account with a valid API key
Create a .env file containing:
AIRFLOW_UID=1000
TMDB_API_KEY=<YOUR_API_KEY>Launch the Airflow, Spark Master, MinIO, and PostgreSQL containers from the project root:
docker compose up -dWait a few minutes until both the Airflow Webserver and Scheduler are healthy.
The complete data pipeline must finish before launching the frontend.
Open the Airflow UI at:
Default credentials:
- Username:
airflow - Password:
airflow
Trigger the movielens_bronze_ingestion DAG. It will automatically trigger both:
movielens_silver_pipelinemovielens_gold_pipeline
which build the Silver and Gold layers, respectively.
Alternatively, trigger it from the terminal:
docker compose run --rm airflow-cli airflow dags trigger movielens_bronze_ingestionOnce the Lakehouse and Vector Database have been fully populated, start the frontend.
To ensure the correct PYTHONPATH and Spark configuration are loaded, execute Streamlit as a Python module using uv:
uv run python -m streamlit run frontend/app.pyThen open:
Enter a user ID to view personalized ALS recommendations, or switch to the AI Search tab and describe the type of movie you'd like to watch in natural language.
docker compose up
β
βΌ
Bronze Ingestion DAG
β
βΌ
Silver Pipeline
β
βΌ
Gold Pipeline
β
βΌ
TMDb Enrichment
β
βΌ
Embedding Generation
β
βΌ
uv run python -m streamlit run frontend/app.py
MovieLens/
βββ assets
βΒ Β βββ MovieLensLayout.png
βΒ Β βββ RAGLayout.png
βββ dags
βΒ Β βββ movielens_pipeline.py
βββ docker
βΒ Β βββ airflow
βΒ Β βΒ Β βββ Dockerfile
βΒ Β βββ postgres
βΒ Β βΒ Β βββ initdb
βΒ Β βΒ Β βββ init-multiple-dbs.sh
βΒ Β βββ spark
βΒ Β βββ Dockerfile
βββ docker-compose.yaml
βββ frontend
βΒ Β βββ app.py
βΒ Β βββ __init__.py
βββ ingestions
βΒ Β βββ __init__.py
βΒ Β βββ movielens_raw.py
βΒ Β βββ tmdb_fetching.py
βββ inspect_tables.py
βββ pyproject.toml
βββ README.md
βββ spark_config.py
βββ transformations
βββ als_recommendations.py
βββ __init__.py
βββ links.py
βββ movie_embeddings.py
βββ movies.py
βββ ratings.py
βββ tags.py
This project uses the MovieLens dataset.
https://files.grouplens.org/datasets/movielens/ml-32m.zip
TMDb API https://developer.themoviedb.org/
- Bronze data ingestion
- Silver data transformations
- Gold recommendation generation
- TMDb metadata enrichment
- Semantic search
- PostgreSQL + pgvector integration
- Streamlit web interface
- Movie poster integration
- Docker image publishing
- CI/CD with GitHub Actions
- Kubernetes deployment
- Recommendation API
This project is licensed under the MIT License. See the LICENSE file for details.



