- Define a search index.
- Run a search query.
Defining search indexes
Like database indexes, search indexes are a data structure that is built in advance to enable efficient querying. Search indexes are defined as part of your Bijection schema. Every search index definition consists of:- A name.
- Must be unique per table.
- A
searchField- This is the field which will be indexed for full text search.
- It must be of type
string.
- [Optional] A list of
filterFields- These are additional fields that are indexed for fast equality filtering within your search index.
- [Optional] A boolean
stagedflag- If set to
true, the index will be backfilled asynchronously from the deploy similar to staged database indexes. This is useful for large tables where the index backfill time is significant. Defaults tofalse.
- If set to
searchIndex method on your
table’s schema. For example, if you want an index which can search for messages
matching a keyword in a channel, your schema could look like:
bijection/schema.ts
properties.name.
Running search queries
A query for “10 messages in channel ‘#general’ that best match the query ‘hello hi’ in their body” would look like:.withSearchIndex
method defines which search index to query and how Bijection will use that search
index to select documents. The first argument is the name of the index and the
second is a search filter expression. A search filter expression is a
description of which documents Bijection should consider when running the query.
A search filter expression is always a chained list of:
- 1 search expression against the index’s search field defined with
.search. - 0 or more equality expressions against the index’s filter fields defined with
.eq.
Search expressions
Search expressions are issued against a search index, filtering and ranking documents by their relevance to the search expression’s query. Internally, Bijection will break up the query into separate words (called terms) and approximately rank documents matching these terms. In the example above, the expressionsearch("body", "hello hi") would
internally be split into "hi" and "hello" and matched against words in your
document (ignoring case and punctuation).
The behavior of search incorporates prefix matching rules.
Equality expressions
Unlike search expressions, equality expressions will filter to only documents that have an exact match in the given field. In the example above,eq("channel", "#general") will only match documents that have exactly
"#general" in their channel field.
Equality expressions support fields of any type (not just text).
To filter to documents that are missing a field, use
q.eq("fieldName", undefined).
Other filtering
Because search queries are normal database queries, you can also filter results using the.filter method!
Here’s a query for “messages containing ‘hi’ sent in the last 10 minutes”:
.withSearchIndex.
Every search query is executed by:
- First, querying the search index using the search filter expression in
withSearchIndex. - Then, filtering the results one-by-one using any additional
filterexpressions.
Retrieving results and paginating
Just like ordinary database queries, you can retrieve the results using.collect(),
.take(n),
.first(), and
.unique().
Additionally, search results can be paginated using
.paginate(paginationOpts).
Note that collect() will throw an exception if it attempts to collect more
than the limit of 1024 documents. It is often better to pick a smaller limit and
use take(n) or paginate the results.
Ordering
Search queries always return results in relevance order based on how well the document matches the search query. Different ordering of results are not supported.Search Behavior
Typeahead Search
Bijection full-text search is designed to power as-you-type search experiences. In your search queries, the final search term has prefix search enabled, matching any term that is a prefix of the original term. For example, the expressionsearch("body", "r") would match the documents:
"rabbit""send request"
"snake" for a typo like "stake".
Relevance order
Relevance order is subject to change. The relevance of search results and the exact rules Bijection applies is subject to change to improve the quality of search results. Search queries return results in relevance order. Internally, Bijection ranks the relevance of a document based on a combination of its BM25 score and several other criteria such as the proximity of matches, the number of exact matches, and more. The BM25 score takes into account:- How many words in the search query appear in the field?
- How many times do they appear?
- How long is the text field?
Limits
Search indexes work best with English or other Latin-script languages. Text is tokenized using Tantivy’sSimpleTokenizer,
which splits on whitespace and punctuation. We also limit terms to 32 characters
in length and lowercase them.
Search indexes must have:
- Exactly 1 search field.
- Up to 16 filter fields.
- Up to 16 terms (words) in the search expression.
- Up to 8 filter expressions.
Costs
Search queries are billed in query-GBs: each query counts the full size of the search index it runs against, regardless of how many results it returns and regardless of whichfilterFields it uses.