Pure functions for search result highlighting and snippet extraction.
This namespace provides functions for highlighting matching terms in search results and extracting relevant snippets. All functions are pure (no side effects).
Architecture: Functional Core (Pure)
Pure functions for search result highlighting and snippet extraction. This namespace provides functions for highlighting matching terms in search results and extracting relevant snippets. All functions are pure (no side effects). Architecture: Functional Core (Pure)
Pure document construction and filter-key conversion for search.
Key functions:
Pure document construction and filter-key conversion for search. Key functions: - defsearch — bind a SearchDefinition to a var (data only) - collect-definitions — the definitions a :wagoe/search component holds - api-enabled? — whether the generic search API serves an index - build-document* — construct a SearchDocument from field values - filter-key->json-key — convert a filter keyword to a snake_case JSON key
What a search asks for, before any store sees it: the sanitized query and
the filter terms. wagoe.search.shell.query-sql turns them into SQL.
What a search asks for, before any store sees it: the sanitized query and the filter terms. `wagoe.search.shell.query-sql` turns them into SQL.
Pure ranking and scoring functions for search results.
This namespace provides functions for calculating relevance scores, applying boosts, and normalizing results. All functions are pure.
Architecture: Functional Core (Pure)
Pure ranking and scoring functions for search results. This namespace provides functions for calculating relevance scores, applying boosts, and normalizing results. All functions are pure. Architecture: Functional Core (Pure)
Port definitions for the wagoe-search library.
ISearchStore — low-level persistence (upsert, delete, search rows) ISearchEngine — high-level orchestration (index-document!, search, suggest)
Port definitions for the wagoe-search library. ISearchStore — low-level persistence (upsert, delete, search rows) ISearchEngine — high-level orchestration (index-document!, search, suggest)
Malli schemas for the wagoe-search library.
All internal data uses kebab-case keywords. snake_case conversion happens only at DB/HTTP boundaries.
Malli schemas for the wagoe-search library. All internal data uses kebab-case keywords. snake_case conversion happens only at DB/HTTP boundaries.
Migratus entry points for search_documents.filters.
Migratus entry points for search_documents.filters.
HTTP API routes and admin web UI handlers for wagoe-search.
API Endpoints (mounted under /api/v1): POST /search/:index-id — search POST /search/:index-id/suggest — trigram suggestions POST /search/documents — index a document DELETE /search/documents/:type/:id — remove a document
Admin Web UI (mounted under /web/admin): GET /search — list all indices GET /search/:index-id — index detail + live search form POST /search/:index-id/search — HTMX search results fragment
Searching takes a signed-in user; the admin pages take the admin role (BOU-568), indexing and removing a platform admin (BOU-954).
Search, suggest and the admin pages serve only an index whose definition
opts in with :api? true or an :api :authorize fn; a hook, when set, must
accept the request. Any other index answers 404, as an unknown one does, so
a caller cannot tell the two apart.
An index whose definition lists :tenant-id among its :filters is
tenant-scoped. A search of one reads the request's resolved tenant, and only
for a caller in it (access/in-tenant-scope?); a tenant_id the caller
sends is dropped. With no tenant resolved, only a global admin may search it, with
whatever filters they send. Anyone else gets 403.
An index without that filter needs :global? true for a caller in a tenant,
unless a platform admin; the admin search page too (BOU-948).
HTTP API routes and admin web UI handlers for wagoe-search. API Endpoints (mounted under /api/v1): POST /search/:index-id — search POST /search/:index-id/suggest — trigram suggestions POST /search/documents — index a document DELETE /search/documents/:type/:id — remove a document Admin Web UI (mounted under /web/admin): GET /search — list all indices GET /search/:index-id — index detail + live search form POST /search/:index-id/search — HTMX search results fragment Searching takes a signed-in user; the admin pages take the admin role (BOU-568), indexing and removing a platform admin (BOU-954). Search, suggest and the admin pages serve only an index whose definition opts in with `:api? true` or an `:api :authorize` fn; a hook, when set, must accept the request. Any other index answers 404, as an unknown one does, so a caller cannot tell the two apart. An index whose definition lists `:tenant-id` among its `:filters` is tenant-scoped. A search of one reads the request's resolved tenant, and only for a caller in it (`access/in-tenant-scope?`); a `tenant_id` the caller sends is dropped. With no tenant resolved, only a global admin may search it, with whatever filters they send. Anyone else gets 403. An index without that filter needs `:global? true` for a caller in a tenant, unless a platform admin; the admin search page too (BOU-948).
Integrant lifecycle management for the search module.
Config keys:
:wagoe/search {:db-ctx (ig/ref :wagoe/db-context) :indexes {index-id definition} ; from config.edn :contributed {index-id definition}} ; modules' :search parts
Returns {:store <ISearchStore> :engine <ISearchEngine>}
:wagoe/search-routes {:search-service (ig/ref :wagoe/search)}
Returns {:api [...] :web [...] :static []} for composition by the HTTP handler.
Integrant lifecycle management for the search module.
Config keys:
:wagoe/search
{:db-ctx (ig/ref :wagoe/db-context)
:indexes {index-id definition} ; from config.edn
:contributed {index-id definition}} ; modules' :search parts
Returns {:store <ISearchStore> :engine <ISearchEngine>}
:wagoe/search-routes
{:search-service (ig/ref :wagoe/search)}
Returns {:api [...] :web [...] :static []} for composition
by the HTTP handler.Database persistence for search documents.
Implements ISearchStore using next.jdbc + HoneySQL for DML and raw parameterized SQL for FTS-specific queries.
Strategies chosen by the adapter's capabilities (ADR-039):
Database persistence for search documents. Implements ISearchStore using next.jdbc + HoneySQL for DML and raw parameterized SQL for FTS-specific queries. Strategies chosen by the adapter's capabilities (ADR-039): - :full-text — to_tsvector/plainto_tsquery + ts_rank + ts_headline, and pg_trgm suggestions where it is installed; without it, a LOWER/LIKE fallback - :on-conflict — INSERT … ON CONFLICT DO UPDATE; without it, delete and insert in one transaction
SQL for a search, from what wagoe.search.core.query describes.
Two query paths:
likeFilter values are matched against the JSON "filters" column using DB-appropriate syntax. Here rather than in core because the SQL is the store's business (BOU-875).
SQL for a search, from what `wagoe.search.core.query` describes. Two query paths: - PostgreSQL: to_tsvector/plainto_tsquery + ts_rank + ts_headline - Fallback (H2/SQLite/MySQL, PostgreSQL suggest without pg_trgm): the database adapter's case-insensitive `like` Filter values are matched against the JSON "filters" column using DB-appropriate syntax. Here rather than in core because the SQL is the store's business (BOU-875).
Deprecated: a process-global registry of search index definitions.
Hand definitions to :wagoe/search instead — under :indexes in config or
a module's :search part — and bind them with
wagoe.search.core.index/defsearch. The search service still reads this
registry for an id its component does not hold, and logs once per such id.
Key functions:
Deprecated: a process-global registry of search index definitions. Hand definitions to `:wagoe/search` instead — under `:indexes` in config or a module's `:search` part — and bind them with `wagoe.search.core.index/defsearch`. The search service still reads this registry for an id its component does not hold, and logs once per such id. Key functions: - defsearch macro — define and register an index - register-search! — low-level registration - get-search — look up by index-id - list-searches — list registered index ids - clear-registry! — reset registry (test fixtures)
SearchService orchestrates document indexing and search queries.
Implements ISearchEngine by coordinating:
SearchService orchestrates document indexing and search queries.
Implements ISearchEngine by coordinating:
- core/index — document construction
- core/query — query sanitization and filter terms
- definitions — the index definitions this service was built with, then
the deprecated global registry
- ISearchStore — persistence operationspg_trgm, which suggestions on PostgreSQL use. Creating it can take a privilege the migration user lacks; suggestions then use LIKE (BOU-661).
pg_trgm, which suggestions on PostgreSQL use. Creating it can take a privilege the migration user lacks; suggestions then use LIKE (BOU-661).
Hiccup UI components for the search Admin interface.
They receive data and return Hiccup. In the shell, not core, because they load wagoe-shared-ui at run time (BOU-932).
Components: field-weight-badge — weight indicator (A/B/C/D) search-result-row — single result row search-results-fragment — HTMX results area indices-page — list all registered indices (full page) index-detail-page — index config + live search test form (full page)
Hiccup UI components for the search Admin interface. They receive data and return Hiccup. In the shell, not core, because they load wagoe-shared-ui at run time (BOU-932). Components: field-weight-badge — weight indicator (A/B/C/D) search-result-row — single result row search-results-fragment — HTMX results area indices-page — list all registered indices (full page) index-detail-page — index config + live search test form (full page)
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |