Search
Give an entity a search: section and people can search its records by
words. The compiler generates the index, keeps it up to date and
generates its migration, and a query finds records with matches. By
default the search runs on PostgreSQL's full-text search, so you need
nothing else. Search is the search capability, so an engine's package,
such as Meilisearch, Typesense, Algolia or OpenSearch, can fill it
instead.
// domains/planning/entities/todo.jadpoentity Todo { ... search: { fields: [title, notes] language: SearchLanguage.english }}// domains/planning/queries/search_todos.jadpoquery search_todos(owner_id: User.id, search_phrase: SearchText) -> Page<TodoView> { from: Todo where: Todo.owner_id == owner_id where: Todo matches search_phrase}
- Fields listed first count most when ordering results.
- With no
order:, the best matches come first, then byid, in keyset pages like every other list (Pages). search_phrasetakes what people type into search boxes: words, quoted phrases and-word, never raw query syntax.search:replaces the full-text indexkind:(Special kinds of index): one declaration, not an index plus hand-written conditions.
An engine instead of PostgreSQL
search: { fields: [...] store: products_index } names a connection
whose package provides search. Leave store: out and the search is
PostgreSQL's. The engine's package does the whole job: it upserts a
record's searchable fields, removes a record, and queries by words with
equality filters.
// domains/catalogue/entities/product.jadpoentity Product { ... search: { fields: [name, description] store: products_index }}
- Only equality filters reach an engine. A
matchesquery on an entity whose search uses an engine may only havewhere:lines that test equality on fields the index holds. Anything else is a compile error naming PostgreSQL search, which can filter any way. - Ids from the engine, records through policy. The engine returns ranked ids, already filtered by tenant. Jadpo then reads those records through the query, with policy applied as for any query (Policy), so a result is never one the caller couldn't read.
- Kept up to date after commit. Every committed change to a
searchable field reaches the engine through the outbox, and is retried
like any delivery
(Delivery: at least once, safe to repeat).
Erasing a person removes their records from the index
(Erasure).
jadpo search reindex <entity>rebuilds the index. - Engine features (synonyms, ranking rules, typo tolerance settings) are the package's own operations, called from a domain the connection lists.
- Development and tests use PostgreSQL search whatever production uses, so nothing leaves the machine and no engine is needed to run a test.
Markdown for agents: /docs/search.md.Built from Jadpo main at a707efb.