Search (Typesense)
Full-text search across all libraries is optional and backed by
Typesense. Without it the server runs fine — the GraphQL search
query just returns nothing. With it, clients get fast, typo-tolerant, multilingual search over
titles, descriptions and genres.
Enabling
-
Run a Typesense instance (one per cluster).
docker-compose-local.ymlshows a working service definition; in Kubernetes the chart can deploy it for you. -
Point the server at it:
TYPESENSE_ENABLED=trueTYPESENSE_HOST=typesenseTYPESENSE_PORT=8108 # defaultTYPESENSE_PROTOCOL=http # defaultTYPESENSE_API_KEY=<the key Typesense was started with> -
Restart the server, then run the
reindexSearchGraphQL mutation once to build the initial index. Until you do, existing media is not searchable — only items touched after enabling would trickle in.
The enabled flag is checked at runtime, not baked into the image: the same image serves both
modes, and search events are simply consumed and discarded while the flag is off. That means you
can flip TYPESENSE_ENABLED with just a restart, no rebuild.
Staying current
After the initial reindex you never need to run it routinely. The index maintains itself:
- new items are indexed when the scanner creates them,
- metadata enrichment (TMDB and friends) updates the entry when it lands,
- deletions remove the entry.
reindexSearch remains the repair tool: it rebuilds into a fresh collection and swaps an
alias, so search stays live during the rebuild. Reach for it after enabling search on an
existing database, after restoring a database backup, or if the index ever looks out of sync.
Adding or removing a language
Search fields are generated per configured language (title_en, description_nl, …) and the
collection schema is fixed at creation time, so a language change is a small procedure:
- Update
ISTER_LANGUAGES(e.g.en,nl,de) and restart the server(s). - Re-fetch metadata so the new language's rows exist in PostgreSQL: run the
analyzeLibrarymutation (or a re-scan) — the index can only surface metadata that exists in the database. - Run
reindexSearchonce. It creates a fresh collection with the new schema and swaps the alias.
Removing a language is the same minus step 2: reindexing simply drops its fields; nothing in PostgreSQL is deleted.
Troubleshooting
- Search returns nothing at all — either
TYPESENSE_ENABLEDis stillfalse, the API key is wrong, orreindexSearchwas never run after enabling. The server log shows connection errors on startup and on each indexing attempt. - New language not searchable — you skipped step 2 or 3 above.
- Index survives server restarts but lives only in Typesense's data dir; if you lose that
volume, one
reindexSearchrebuilds everything from PostgreSQL. It is disposable — see Maintenance.
How indexing works internally is described in the architecture documentation.