3-hour hands-on workshop building a movie recommendation system with Valkey Search.
- Git
- Python 3
- A container runtime (Podman or Docker)
- Jupyter Notebook
winget install --id Git.Git -e --source winget
winget install Python.Python.3Close and reopen PowerShell after installing.
Podman (recommended, free, no license restrictions):
First install WSL2 (open PowerShell as Administrator):
wsl --install --no-distributionRestart your computer, then:
winget install RedHat.PodmanClose and reopen PowerShell, then:
podman machine init
podman machine startOr Docker Desktop (free for personal/education use): Download from https://www.docker.com/products/docker-desktop/
pip install notebookgit clone https://github.com/KarthikSubbarao/valkey-search-workshop.git
cd valkey-search-workshop
python -m notebook valkey_search_workshop.ipynbYou need git, python3, and a container runtime. If already installed, skip to step 3.
Using Homebrew:
brew install git pythonPodman (recommended):
brew install podman
podman machine init
podman machine startOr Colima + Docker CLI:
brew install docker colima
colima startOr Docker Desktop: Download from https://www.docker.com/products/docker-desktop/
pip install notebookgit clone https://github.com/KarthikSubbarao/valkey-search-workshop.git
cd valkey-search-workshop
python -m notebook valkey_search_workshop.ipynb# Ubuntu/Debian
sudo apt install git python3 python3-pip podman
# Fedora/RHEL
sudo dnf install git python3 python3-pip podmanpip install notebookgit clone https://github.com/KarthikSubbarao/valkey-search-workshop.git
cd valkey-search-workshop
python -m notebook valkey_search_workshop.ipynb- Click Run (▶) on each cell from top to bottom, or use Shift+Enter
- The first cell starts Valkey automatically
- Wait for each cell to finish (the
[*]becomes a number) before running the next
podman rm -f valkey # or: docker rm -f valkey
podman machine stop # optionalvalkey-search-workshop/
├── valkey_search_workshop.ipynb # Workshop (with exercises)
├── valkey_search_workshop_solved.ipynb # Reference (with solutions)
├── README.md
└── data/
├── catalog.csv # 10,000 movies with 768-dim embeddings (TMDB)
└── ratings.csv # 60,000 user ratings from 500 users (MovieLens 32M)
Subset of Remsky/Embeddings__Ultimate_1Million_Movies_Dataset on HuggingFace (~680K movies total). Original data sourced from TMDB Movies Dataset 2025 on Kaggle by Alan Vourch, with 768-dim embeddings generated by Jeremy Braun (Remsky) using nomic-embed-text via Ollama.
We extracted 10,000 movies matching those watched by our selected MovieLens users.
| Column | Type | Description |
|---|---|---|
| tmdb_id | int | TMDB movie ID (key: movie:{tmdb_id}) |
| title | string | Movie title |
| overview | string | Plot description |
| genres | string | Comma-separated genre tags |
| tmdb_rating | float | Crowd-sourced TMDB user score (0-10) |
| tmdb_popularity | float | TMDB external buzz/attention metric |
| language | string | Original language code (en, fr, etc.) |
| embedding | floats | 768-dim nomic-embed-text embedding of title+tagline+overview |
Subset of MovieLens 32M by GroupLens Research (32M ratings from 200K users total). We selected 500 users with 50-300 ratings each, pre-joined with movie metadata (title, genres, tmdb_id) so no additional files are needed at load time.
| Column | Type | Description |
|---|---|---|
| user_id | int | MovieLens user ID |
| title | string | Movie title |
| genres | string | Comma-separated genre tags |
| tmdb_id | int | TMDB ID (links to movie:{tmdb_id} in catalog) |
| user_rating | float | This user's rating (0.5-5.0) |
| timestamp | int | Unix epoch when they rated it |
| Index | Type | Purpose |
|---|---|---|
idx:movies |
Global | Catalog search, vector similarity (KNN) |
idx:user:{id}:history |
Single-slot (hash-tagged) | Per-user queries, sub-ms |
idx:watch |
Global | Cross-user analytics (FT.AGGREGATE) |