{
  "schema_version": 2,
  "id": "develop/clients/nodejs/vecsets",
  "title": "Vector set embeddings",
  "url": "https://redis.io/docs/latest/develop/clients/nodejs/vecsets/",
  "summary": "Index and query embeddings with Redis vector sets",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-09-08T15:03:39+01:00",
  "page_type": "content",
  "content_hash": "3d2593cfc48d277097022f9c9eedef4922c2fd8543ce6438bd8bd8a41439d68b",
  "sections": [
    {
      "id": "initialize",
      "title": "Initialize",
      "role": "content",
      "text": "Start by [installing](https://redis.io/docs/latest/develop/clients/nodejs#install) `node-redis`\nif you haven't already done so. Also, install `@xenova/transformers`:\n\n[code example]\n\nIn your JavaScript source file, import the required classes:\n\nFoundational: Import Redis client and transformer modules for vector set operations\n\n**Difficulty:** Beginner\n\n**Available in:** JavaScript (Node.js)\n\n##### JavaScript (Node.js)\n\n[code example]\n\n\n\nThe first of these imports is the\n`@xenova/transformers` class, which generates an embedding from a section of text.\nThis example uses `transformers.pipeline` with the\n[`all-MiniLM-L6-v2`](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2)\nmodel for the embeddings. This model generates vectors with 384 dimensions, regardless\nof the length of the input text, but note that the input is truncated to 256\ntokens (see\n[Word piece tokenization](https://huggingface.co/learn/nlp-course/en/chapter6/6)\nat the [Hugging Face](https://huggingface.co/) docs to learn more about the way tokens\nare related to the original text).\n\nThe output from `transformers.pipeline` is a function (called `pipe` in the examples)\nthat you can call to generate embeddings. The `pipeOptions` object is a parameter for\n`pipe` that specifies how to generate sentence embeddings from token embeddings (see the\n[`all-MiniLM-L6-v2`](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2)\ndocumentation for details).\n\nFoundational: Configure a transformer pipeline to generate text embeddings for vector set operations\n\n**Difficulty:** Beginner\n\n**Available in:** JavaScript (Node.js)\n\n##### JavaScript (Node.js)\n\n[code example]"
    },
    {
      "id": "create-the-data",
      "title": "Create the data",
      "role": "content",
      "text": "The example data is contained in an object with some brief\ndescriptions of famous people:\n\nFoundational: Define sample data structures with descriptions for vector set examples\n\n**Difficulty:** Beginner\n\n**Available in:** JavaScript (Node.js)\n\n##### JavaScript (Node.js)\n\n[code example]"
    },
    {
      "id": "add-the-data-to-a-vector-set",
      "title": "Add the data to a vector set",
      "role": "content",
      "text": "The next step is to connect to Redis and add the data to a new vector set.\n\nThe code below iterates through all the key-value pairs in the `peopleData` object\nand adds corresponding elements to a vector set called `famousPeople`.\n\nUse the `pipe()` function created above to generate the\nembedding and then use `Array.from()` to convert the embedding to an array\nof `float32` values that you can pass to the\n[`vAdd()`](https://redis.io/docs/latest/commands/vadd) command to set the embedding.\n\nThe call to `vAdd()` also adds the `born` and `died` values from the\n`peopleData` object as attribute data. You can access this during a query\nor by using the [`vGetAttr()`](https://redis.io/docs/latest/commands/vgetattr) method.\n\nPractical pattern: Generate embeddings and add elements to a vector set with vAdd() and attribute metadata\n\n**Difficulty:** Intermediate\n\n**Available in:** JavaScript (Node.js)\n\n##### JavaScript (Node.js)\n\n[code example]"
    },
    {
      "id": "query-the-vector-set",
      "title": "Query the vector set",
      "role": "content",
      "text": "You can now query the data in the set. The basic approach is to use the\n`pipe()` function to generate another embedding vector for the query text.\n(This is the same method used to add the elements to the set.) Then, pass\nthe query vector to [`vSim()`](https://redis.io/docs/latest/commands/vsim) to return elements\nof the set, ranked in order of similarity to the query.\n\nStart with a simple query for \"actors\":\n\nVector set query: Execute a basic vector similarity search using vSim() to find semantically similar elements\n\n**Difficulty:** Intermediate\n\n**Available in:** JavaScript (Node.js)\n\n##### JavaScript (Node.js)\n\n[code example]\n\n\n\nThis returns the following list of elements (formatted slightly for clarity):\n\n[code example]\n\nThe first two people in the list are the two actors, as expected, but none of the\npeople from Linus Pauling onward was especially well-known for acting (and there certainly\nisn't any information about that in the short description text).\nAs it stands, the search attempts to rank all the elements in the set, based\non the information contained in the embedding model.\nYou can use the `COUNT` parameter of `vSim()` to limit the list of elements\nto just the most relevant few items:\n\nRestrict results: Limit vector search results using the COUNT parameter to return only the most relevant matches\n\n**Difficulty:** Intermediate\n\n**Available in:** JavaScript (Node.js)\n\n##### JavaScript (Node.js)\n\n[code example]\n\n\n\nThe reason for using text embeddings rather than simple text search\nis that the embeddings represent semantic information. This allows a query\nto find elements with a similar meaning even if the text is\ndifferent. For example, the word \"entertainer\" doesn't appear in any of the\ndescriptions but if you use it as a query, the actors and musicians are ranked\nhighest in the results list:\n\nSemantic search: Find elements with similar meaning despite different text\n\n**Difficulty:** Intermediate\n\n**Available in:** JavaScript (Node.js)\n\n##### JavaScript (Node.js)\n\n[code example]\n\n\n\nSimilarly, if you use \"science\" as a query, you get the following results:\n\n[code example]\n\nThe scientists are ranked highest but they are then followed by the\nmathematicians. This seems reasonable given the connection between mathematics\nand science.\n\nYou can also use\n[filter expressions](https://redis.io/docs/latest/develop/data-types/vector-sets/filtered-search)\nwith `vSim()` to restrict the search further. For example,\nrepeat the \"science\" query, but this time limit the results to people\nwho died before the year 2000:\n\nPre-filtering: Combine vector similarity search with filter expressions to restrict results based on attribute metadata\n\n**Difficulty:** Advanced\n\n**Available in:** JavaScript (Node.js)\n\n##### JavaScript (Node.js)\n\n[code example]\n\n\n\nNote that the boolean filter expression is applied to items in the list\nbefore the vector distance calculation is performed. Items that don't\npass the filter test are removed from the results completely, rather\nthan just reduced in rank. This can help to improve the performance of the\nsearch because there is no need to calculate the vector distance for\nelements that have already been filtered out of the search."
    },
    {
      "id": "more-information",
      "title": "More information",
      "role": "content",
      "text": "See the [vector sets](https://redis.io/docs/latest/develop/data-types/vector-sets)\ndocs for more information and code examples. See the\n[Redis for AI](https://redis.io/docs/latest/develop/ai) section for more details\nabout text embeddings and other AI techniques you can use with Redis.\n\nYou may also be interested in\n[vector search](https://redis.io/docs/latest/develop/clients/nodejs/vecsearch).\nThis is a feature of\n[Redis Search](https://redis.io/docs/latest/develop/ai/search-and-query)\nthat lets you retrieve\n[JSON](https://redis.io/docs/latest/develop/data-types/json) and\n[hash](https://redis.io/docs/latest/develop/data-types/hashes) documents based on\nvector data stored in their fields."
    }
  ],
  "examples": [
    {
      "id": "initialize-ex0",
      "language": "bash",
      "code": "npm install @xenova/transformers",
      "section_id": "initialize"
    },
    {
      "id": "initialize-ex1",
      "language": "javascript",
      "code": "import * as transformers from '@xenova/transformers';\nimport { createClient } from 'redis';",
      "section_id": "initialize"
    },
    {
      "id": "initialize-ex2",
      "language": "javascript",
      "code": "const pipe = await transformers.pipeline(\n    'feature-extraction', 'Xenova/all-MiniLM-L6-v2'\n);\n\nconst pipeOptions = {\n    pooling: 'mean',\n    normalize: true,\n};",
      "section_id": "initialize"
    },
    {
      "id": "create-the-data-ex0",
      "language": "javascript",
      "code": "const peopleData = {\n    \"Marie Curie\": {\n        \"born\": 1867, \"died\": 1934,\n        \"description\": `\n        Polish-French chemist and physicist. The only person ever to win\n        two Nobel prizes for two different sciences.\n        `\n    },\n    \"Linus Pauling\": {\n        \"born\": 1901, \"died\": 1994,\n        \"description\": `\n        American chemist and peace activist. One of only two people to win two\n        Nobel prizes in different fields (chemistry and peace).\n        `\n    },\n    \"Freddie Mercury\": {\n        \"born\": 1946, \"died\": 1991,\n        \"description\": `\n        British musician, best known as the lead singer of the rock band\n        Queen.\n        `\n    },\n    \"Marie Fredriksson\": {\n        \"born\": 1958, \"died\": 2019,\n        \"description\": `\n        Swedish multi-instrumentalist, mainly known as the lead singer and\n        keyboardist of the band Roxette.\n        `\n    },\n    \"Paul Erdos\": {\n        \"born\": 1913, \"died\": 1996,\n        \"description\": `\n        Hungarian mathematician, known for his eccentric personality almost\n        as much as his contributions to many different fields of mathematics.\n        `\n    },\n    \"Maryam Mirzakhani\": {\n        \"born\": 1977, \"died\": 2017,\n        \"description\": `\n        Iranian mathematician. The first woman ever to win the Fields medal\n        for her contributions to mathematics.\n        `\n    },\n    \"Masako Natsume\": {\n        \"born\": 1957, \"died\": 1985,\n        \"description\": `\n        Japanese actress. She was very famous in Japan but was primarily\n        known elsewhere in the world for her portrayal of Tripitaka in the\n        TV series Monkey.\n        `\n    },\n    \"Chaim Topol\": {\n        \"born\": 1935, \"died\": 2023,\n        \"description\": `\n        Israeli actor and singer, usually credited simply as 'Topol'. He was\n        best known for his many appearances as Tevye in the musical Fiddler\n        on the Roof.\n        `\n    }\n};",
      "section_id": "create-the-data"
    },
    {
      "id": "add-the-data-to-a-vector-set-ex0",
      "language": "javascript",
      "code": "const client = createClient({ url: 'redis://localhost:6379' });\n\nclient.on('error', err => console.log('Redis Client Error', err));\nawait client.connect();\n\nfor (const [name, details] of Object.entries(peopleData)) {\n    const embedding = await pipe(details.description, pipeOptions);\n    const embeddingArray = Array.from(embedding.data);\n\n    await client.vAdd('famousPeople', embeddingArray, name);\n    await client.vSetAttr('famousPeople', name, JSON.stringify({\n        born: details.born,\n        died: details.died\n    }));\n}",
      "section_id": "add-the-data-to-a-vector-set"
    },
    {
      "id": "query-the-vector-set-ex0",
      "language": "javascript",
      "code": "const queryValue = \"actors\";\n\nconst queryEmbedding = await pipe(queryValue, pipeOptions);\nconst queryArray = Array.from(queryEmbedding.data);\n\nconst actorsResults = await client.vSim('famousPeople', queryArray);\n\nconsole.log(`'actors': ${JSON.stringify(actorsResults)}`);\n// >>> 'actors': [\"Masako Natsume\",\"Chaim Topol\",\"Linus Pauling\",\n// \"Marie Fredriksson\",\"Maryam Mirzakhani\",\"Freddie Mercury\",\n// \"Marie Curie\",\"Paul Erdos\"]",
      "section_id": "query-the-vector-set"
    },
    {
      "id": "query-the-vector-set-ex1",
      "language": "plaintext",
      "code": "'actors': [\"Masako Natsume\",\"Chaim Topol\",\"Linus Pauling\",\n    \"Marie Fredriksson\",\"Maryam Mirzakhani\",\"Freddie Mercury\",\n    \"Marie Curie\",\"Paul Erdos\"]",
      "section_id": "query-the-vector-set"
    },
    {
      "id": "query-the-vector-set-ex2",
      "language": "javascript",
      "code": "const queryValue2 = \"actors\";\n\nconst queryEmbedding2 = await pipe(queryValue2, pipeOptions);\nconst queryArray2 = Array.from(queryEmbedding2.data);\n\nconst twoActorsResults = await client.vSim('famousPeople', queryArray2, {\n    COUNT: 2\n});\n\nconsole.log(`'actors (2)': ${JSON.stringify(twoActorsResults)}`);\n// >>> 'actors (2)': [\"Masako Natsume\",\"Chaim Topol\"]",
      "section_id": "query-the-vector-set"
    },
    {
      "id": "query-the-vector-set-ex3",
      "language": "javascript",
      "code": "const queryValue3 = \"entertainer\";\n\nconst queryEmbedding3 = await pipe(queryValue3, pipeOptions);\nconst queryArray3 = Array.from(queryEmbedding3.data);\n\nconst entertainerResults = await client.vSim('famousPeople', queryArray3);\n\nconsole.log(`'entertainer': ${JSON.stringify(entertainerResults)}`);\n// >>> 'actors': [\"Masako Natsume\",\"Chaim Topol\",\"Linus Pauling\",\n// \"Marie Fredriksson\",\"Maryam Mirzakhani\",\"Freddie Mercury\",\n// \"Marie Curie\",\"Paul Erdos\"]",
      "section_id": "query-the-vector-set"
    },
    {
      "id": "query-the-vector-set-ex4",
      "language": "plaintext",
      "code": "'science': [\"Linus Pauling\",\"Marie Curie\",\"Maryam Mirzakhani\",\"Paul Erdos\",\n\"Marie Fredriksson\",\"Masako Natsume\",\"Freddie Mercury\",\"Chaim Topol\"]",
      "section_id": "query-the-vector-set"
    },
    {
      "id": "query-the-vector-set-ex5",
      "language": "javascript",
      "code": "const queryValue5 = \"science\";\n\nconst queryEmbedding5 = await pipe(queryValue5, pipeOptions);\nconst queryArray5 = Array.from(queryEmbedding5.data);\n\nconst science2000Results = await client.vSim('famousPeople', queryArray5, {\n    FILTER: '.died < 2000'\n});\n\nconsole.log(`'science2000': ${JSON.stringify(science2000Results)}`);\n// >>> 'science2000': [\"Linus Pauling\",\"Marie Curie\",\"Paul Erdos\",\n// \"Masako Natsume\",\"Freddie Mercury\"]",
      "section_id": "query-the-vector-set"
    }
  ]
}
