content/develop/clients/nodejs/vecsearch.md
[Redis Search]({{< relref "/develop/ai/search-and-query" >}}) lets you index vector fields in [hash]({{< relref "/develop/data-types/hashes" >}}) or [JSON]({{< relref "/develop/data-types/json" >}}) objects (see the [Vectors]({{< relref "/develop/ai/search-and-query/vectors" >}}) reference page for more information).
Vector fields can store text embeddings, which are AI-generated vector representations of text content. The [vector distance]({{< relref "/develop/ai/search-and-query/vectors#distance-metrics" >}}) between two embeddings measures their semantic similarity. When you compare the similarity of a query embedding with stored embeddings, Redis can retrieve documents that closely match the query's meaning.
In the example below, we use the
@xenova/transformers
library to generate vector embeddings to store and index with
Redis Search. The code is first demonstrated for hash documents with a
separate section to explain the
differences with JSON documents.
{{< note >}}From v5.0.0
onwards, node-redis uses query dialect 2 by default.
Redis Search methods such as [ft.search()]({{< relref "/commands/ft.search" >}})
will explicitly request this dialect, overriding the default set for the server.
See
[Query dialects]({{< relref "/develop/ai/search-and-query/advanced-concepts/dialects" >}})
for more information.
{{< /note >}}
Install the required dependencies:
node-redis]({{< relref "/develop/clients/nodejs" >}}) if you haven't already.@xenova/transformers:npm install @xenova/transformers
In your JavaScript source file, import the required classes:
{{< clients-example set="home_query_vec" step="import" lang_filter="Node.js" description="Foundational: Import Redis client and transformer modules for vector embedding operations" difficulty="beginner" >}} {{< /clients-example >}}
The @xenova/transformers module handles embedding models. This example uses the
all-distilroberta-v1
model, which:
The pipe function generates embeddings. The pipeOptions object specifies how to generate sentence embeddings from token embeddings (see the
all-distilroberta-v1
documentation for details):
{{< clients-example set="home_query_vec" step="pipeline" lang_filter="Node.js" description="Foundational: Configure a transformer pipeline to generate vector embeddings from text" difficulty="beginner" >}} {{< /clients-example >}}
First, connect to Redis and remove any existing index named vector_idx:
{{< clients-example set="home_query_vec" step="connect" lang_filter="Node.js" description="Foundational: Connect to Redis and clean up existing vector indexes" difficulty="beginner" >}} {{< /clients-example >}}
Next, create the index with the following schema:
content: Text field for the content to indexgenre: [Tag]({{< relref "/develop/ai/search-and-query/advanced-concepts/tags" >}})
field representing the text's genreembedding: [Vector]({{< relref "/develop/ai/search-and-query/vectors" >}})
field with:
{{< clients-example set="home_query_vec" step="create_index" lang_filter="Node.js" description="Foundational: Create a vector search index with HNSW algorithm and L2 distance metric for semantic search" difficulty="intermediate" >}} {{< /clients-example >}}
Add data objects to the index using hSet(). The index automatically processes objects with the doc: prefix.
For each document:
pipe() function and pipeOptionsBuffer.from()hSet()Use Promise.all() to batch the commands and reduce network round trips:
{{< clients-example set="home_query_vec" step="add_data" lang_filter="Node.js" description="Practical pattern: Generate embeddings and store documents with vector fields using pipelined hSet() commands" difficulty="intermediate" >}} {{< /clients-example >}}
To query the index:
The query returns an array of document objects. Each object contains:
id: The document's keyvalue: An object with fields specified in the RETURN option{{< clients-example set="home_query_vec" step="query" lang_filter="Node.js" description="Vector query: Execute a vector similarity search by generating a query embedding and finding nearest neighbors" difficulty="intermediate" >}} {{< /clients-example >}}
The first run may take longer as it downloads the model data. The output shows results ordered by score (vector distance), with lower scores indicating greater similarity:
doc:1: 'That is a very happy person', Score: 0.127055495977
doc:2: 'That is a happy dog', Score: 0.836842417717
doc:3: 'Today is a sunny day', Score: 1.50889515877
JSON documents support richer data modeling with nested fields. Key differences from hash documents:
AS optionON to JSON when creating the indexjson.set() instead of hSet()Create the index with path aliases:
{{< clients-example set="home_query_vec" step="json_index" lang_filter="Node.js" description="Foundational: Create a vector search index for JSON documents with path aliases and nested field support" difficulty="intermediate" >}} {{< /clients-example >}}
Add data using json.set(). Convert the Float32Array to a standard JavaScript array using the spread operator:
{{< clients-example set="home_query_vec" step="json_data" lang_filter="Node.js" description="Practical pattern: Store JSON documents with vector embeddings converted to arrays for nested field support" difficulty="intermediate" >}} {{< /clients-example >}}
Query JSON documents using the same syntax, but note that the vector parameter must still be a binary string:
{{< clients-example set="home_query_vec" step="json_query" lang_filter="Node.js" description="Vector query: Execute vector similarity search on JSON documents with the same query syntax as hash documents" difficulty="intermediate" >}} {{< /clients-example >}}
The results are identical to the hash document query, except for the jdoc: prefix:
jdoc:1: 'That is a very happy person', Score: 0.127055495977
jdoc:2: 'That is a happy dog', Score: 0.836842417717
jdoc:3: 'Today is a sunny day', Score: 1.50889515877
See [Vector search]({{< relref "/develop/ai/search-and-query/query/vector-search" >}}) for more information about indexing options, distance metrics, and query format.