On this page

Search your tables

Full-text and semantic search over your tables from any SDK: pick the columns, StitchDB keeps the index current and applies your row level security.

Make a table searchable in two clicks and query it from your app. StitchDB ranks matches by words (with stemming, "phrases", or and -exclusions) and, if you turn it on, by meaning, so a search for automobile also finds car. Results are rows of your table, filtered by its row level security policies exactly like the REST API.

#Add a search index

In Database › Search (project owners and admins) choose a table, its text columns and a language, and whether to also search by meaning. The table needs a primary key. Put the most important column first: a match in the first column ranks above one in the second, and so on. Existing rows are indexed at once; after that, inserts, updates and deletes are picked up by a trigger in the same transaction.

SettingWhat it does
ColumnsUp to 8 columns: text, varchar, text arrays, json and jsonb, and numbers, dates or uuids (matched as words). Their text is combined into one document per row.
Languageenglish, german, french and others stem words, so running finds run. Any (simple) matches words exactly, for names, codes and mixed languages.
Search by meaningEach row is turned into an embedding (a list of numbers) in the background, usually within seconds. Changed rows are embedded again; rows whose text did not change are not.

#Search from your app

JavaScript
const { data, error } = await stitchdb.search('posts', 'running shoes', { limit: 20 })

// words only, with phrase and exclusion, two columns back
const { data: exact } = await stitchdb.search('posts', '"trail running" -sale', { mode: 'keyword', select: 'id,title' })

Or over HTTP, with the project API key and, for a signed-in user, their access token, as for the REST API:

Terminal
curl 'https://<ref>.p.stitchdb.com/search/v1/posts?q=running%20shoes&limit=20' \
  -H "apikey: $STITCHDB_ANON_KEY" \
  -H "Authorization: Bearer $USER_ACCESS_TOKEN"
ParameterMeaning
qThe search text, up to 500 characters.
limit1 to 100 results, 20 by default.
modehybrid (words and meaning, merged; the default when the index searches by meaning), keyword or semantic.
selectComma-separated columns to return; all columns by default.

The answer is { data, scores, mode }: the rows, best first, and for each one its score, keyword_rank and semantic_rank (null if that method did not find it). Use POST /search/v1/<table> with a JSON body for long queries. Tables outside public are named schema.table.

#Semantic search and the monthly amount

Keyword search works on every plan; semantic and hybrid search are included from the Pro plan. Embedding rows and search texts is included in each plan up to a monthly number of embeddings (one per changed row and one per new search text; repeated searches are cached). When it runs out, hybrid searches keep working with words only and say so in note, semantic searches return 429, and new rows wait until next month. To remove the limit, add your own OpenAI-compatible embeddings key in Search › Semantic search: requests then go from your project's server straight to that provider.

#Good to know

  • The index lives in your database (schema _stitch_search) and counts toward its size, roughly the size of the indexed text plus 6 KB per row for meaning.
  • Studio's Try box searches by words as the table owner, without row level security. Your app's searches always apply it.
  • Deleting an index removes its trigger and documents; your table is not changed.
LimitFreeProScaleEnterprise
Search indexes per project11050200
Semantic search embeddings per project per month0500,0002,000,00010,000,000