# Vector Search

Typesense supports the ability to add embeddings generated by your Machine Learning models to each document, and then doing a nearest-neighbor search on them. This lets you build features like similarity search, recommendations, semantic search, visual search, etc.

# What is an embedding?

An embedding for a JSON document is just an array of floating point numbers (eg: [0.4422, 0.49292, 0.1245, ...]), that is an alternate numeric representation of the document.

These embeddings are generated by Machine Learning models in such a way that documents that are "similar" to each other (for different definitions of similarity depending on the model used), have embeddings that are "closer" to each other (cosine similarity).

Here are some common models you can use to generate these document embeddings: Sentence-BERT, CLIP, OpenAI's Embeddings model, word2vec, etc.

Once you've generated these embeddings, you can import them into Typesense into a special vector field and then do a nearest neighbor search, giving another set of vectors or a document ID as the input, and get the documents that are closest (cosine similarity) to your input.

Here's an example practical application of vector search - a "Find Similar" feature in an ecommerce store: ecommerce-store.typesense.org (opens new window). (Click on Find Similar below each product).

Here are two articles that go into more depth about embeddings:

Let's now discuss how to do index and search embeddings in Typesense.

# Adding a Vector Field

We'll assume that you've already generated your embeddings using a machine learning model. If not, here's (opens new window) a quick example of how to use the Sentence-BERT model to generate embeddings.

Once you have your document embeddings, you want to add a float[] field to your collection schema that holds these embeddings, and specify the number of dimensions (length of the float array) via the num_dim property.

Let's create a collection called docs with a vector field called vec that contains just 4 dimensions.

Let's now index a document with a vector.

We can now search for documents that contain a vec field value "closest" to a given query vector.

We use the k parameter to control the number of documents that are returned.

TIP

Since vector search queries tend to be large because of the large dimension of the query vector, we are using the multi_search end-point that sends the search parameters as a POST request body.

Sample Response

# Querying for similar documents

If you have a particular document id and want to find documents that are "similar" to this document, you can do a vector query that references this id directly.

curl 'http://localhost:8108/multi_search?collection=docs' -X POST -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
--data-raw '{"searches":[{"q":"*", "vector_query": "vec:([], id: foobar)" }]}'

By specifying an empty query vector [] and passing an id parameter, this query would return all documents whose vec value is closest to the foobar document's vec value.

TIP

The foobar document itself will not be returned in the results.

# Brute-force searching

By default, Typesense uses the built-in HNSW index to do approximate nearest neighbor vector searches. This scales well for large datasets. However, if you wish to bypass the HNSW index and do a flat / brute-force ranking of vectors, you can do that via the flat_search_cutoff parameter.

For example, if you wish to do brute-force vector search when a given query matches fewer than 20 documents, sending flat_search_cutoff=20 will bypass the HNSW index when the number of results found is less than 20.

Here's an example where we are filtering on the category field and asking the vector search to use direct flat searching if the number of results produced by the filtering operation is less than 20 results.

curl 'http://localhost:8108/multi_search?collection=docs' -X POST -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
--data-raw '{"searches":[{"q":"*", "filter_by": "category:shoes", "vector_query": "vec:([0.96826, 0.94, 0.39557, 0.306488], k:100, flat_search_cutoff: 20)" }]}'

# UI Examples

Last Updated: 5/9/2023, 2:13:41 AM