Skip to content

Full-text search

Mark text fields searchable and query them with ?search= on the list endpoint, newest first or ranked by relevance.

Vaultbase can full-text search a collection’s text fields using SQLite’s built-in FTS5 engine. There’s nothing to install and no external service: the index lives in the same database file and stays in sync on every write.

In the admin, open the collection, select a field and turn on Searchable. Or set it in the field options:

{ "name": "title", "type": "text", "options": { "searchable": true } }
  • Works on text, editor, email and url fields.
  • Not allowed together with encrypted. Only ciphertext is stored, so there’s nothing useful to index.
  • Base and auth collections only. View collections can’t be searched.

Turning the option on builds the index from existing records. Turning it off on every field drops the index.

GET /api/v1/posts?search=quick brown fox
  • Every word must match (AND). The last word matches as a prefix, so ?search=vaul finds “vaultbase”. That makes it suitable for search-as-you-type.
  • Matching ignores case and accents: cafe finds “Café”. Any language that separates words with spaces works, including Arabic.
  • FTS syntax in the input (OR, NEAR, quotes, -, col:) is matched as plain text, so user input can be passed straight through.
  • Results are newest first unless you pass sort (since v0.27.0). Newest first stops at the page, so a word in every record costs no more than a rare one. sort=@rank orders by relevance (BM25 on SQLite, ts_rank on Postgres), which scores every match before returning a page: about 130 ms for a word in 100,000 records.
  • search combines with filter, expand, fields, pagination and the collection’s list rule. Callers only ever see records they could list anyway.
  • search on a collection with no searchable fields returns 400. A blank search is ignored.

With the SDK:

const res = await vb.collection("posts").list({ search: "quick brown", perPage: 20 });

search also narrows the candidates for nearVector. Keyword matches are then ranked by embedding similarity.

Each collection with searchable fields gets an FTS5 table vb_<collection>_fts that indexes the searchable columns of vb_<collection>. Triggers on the record table keep it up to date. That covers writes from the records API, batch, hooks, cascades, auth flows and admin SQL alike. The index is checked at startup and rebuilt if it’s missing or out of date, for example after restoring an older backup.

editor fields are indexed as stored, HTML tags included. Searching for a tag name such as p will match most editor content.

On Postgres the index is a generated tsvector column, vb_search, on vb_<collection> with a GIN index on it. Postgres keeps it current on every write, so the same write paths are covered. Accents are folded through the unaccent extension, which Vaultbase enables at start when the database allows it (every major managed provider does); without it, matching is still case-insensitive but cafe no longer finds “Café”. The vb_search name is reserved and never appears in records. Tag names in editor content are not indexed on Postgres.