From d46ff6af3d67a351a43f0b18ad465069a84968ed Mon Sep 17 00:00:00 2001 From: ogzhanolguncu Date: Tue, 16 Jan 2024 13:04:10 +0300 Subject: [PATCH] Update readme and docs --- README.md | 220 ++++++++++++++++++++++- index.ts | 10 +- package.json | 2 +- src/commands/client/delete/index.test.ts | 21 ++- src/commands/client/delete/index.ts | 39 +--- src/commands/client/fetch/index.test.ts | 32 ++-- src/commands/client/fetch/index.ts | 38 +--- src/commands/client/query/index.test.ts | 2 +- src/commands/client/query/index.ts | 37 +--- src/commands/client/range/index.ts | 45 +---- src/commands/client/reset/index.test.ts | 20 ++- src/commands/client/reset/index.ts | 7 - src/commands/client/upsert/index.test.ts | 19 +- src/commands/client/upsert/index.ts | 33 +--- src/http/index.ts | 26 +-- src/vector.ts | 112 +++++++++++- 16 files changed, 430 insertions(+), 233 deletions(-) diff --git a/README.md b/README.md index a9d314c..a15a6c7 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,221 @@ -# vector-sdk +# Upstash Vector Node.js Client -To install dependencies: +This is the official Node.js client for [Upstash](https://upstash.com/), written in TypeScript. -```bash -bun install +## Documentation + +- [**Reference Documentation**](https://upstash.com/docs/vector/overall/getstarted) + +## Installation + +``` +npm install @upstash/vector +pnpm add @upstash/vector ``` -To run: +## Usage + +### Initializing the client + +There are two pieces of configuration required to use the Upstash vector client: an REST token and REST URL. These values can be passed using environment variables or in code through a configuration object. Find your configuration values in the console dashboard at [https://console.upstash.com/](https://console.upstash.com/). + +#### Using environment variables + +The environment variables used to configure the client are the following: ```bash -bun run index.ts +UPSTASH_VECTOR_REST_URL="your_rest_url" +UPSTASH_VECTOR_REST_TOKEN="your_rest_token" +``` + +When these environment variables are set, the client constructor does not require any additional arguments. + +```typescript +import { fromEnv } from "@upstash/vector"; + +const index = fromEnv(); +``` + +#### Using a configuration object + +If you prefer to pass configuration in code, the constructor accepts a config object containing the `url` and `token` values. This +could be useful if your application needs to interact with multiple projects, each with a different configuration. + +```typescript +import { Index } from "@upstash/vector"; + +const index = new Index({ + url: "", + token: "", +}); +``` + +## Index operations + +Upstash vector indexes support operations for working with vector data using operations such as upsert, query, fetch, and delete. + +### Targeting an index + +To perform data operations on an index, you target it using the `index` method. + +```typescript +const index = new Index(); + +// Now perform index operations +await index.fetch([1, 2, 3], { includeMetadata: true, includeVectors: true }); +``` + +### Targeting an index, with metadata typing + +If you are storing metadata alongside your vector values, you can pass a type parameter to `index()` in order to get proper TypeScript typechecking. + +```typescript +const index = new Index(); + +type Metadata = { + title: string, + genre: 'sci-fi' | 'fantasy' | 'horror' | 'action' +} + +await index.upsert([{ + id: '1234', + vector: [ + .... // embedding values + ], + metadata: { + title: 'Lord of The Rings', + genre: 'drama', + category: 'classic' + } +}]) + +const results = await index.query({ + vector: [ + ... // query embedding + ], + includeVectors: true, + topK: 1, +}) + +if (results[0].metadata) { + // Since we passed the Metadata type parameter above, + // we can interact with metadata fields without having to + // do any typecasting. + const { title, genre, category } = movie.metadata; + console.log(`The best match in fantasy was ${title}`) +} ``` -This project was created using `bun init` in bun v1.0.4. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. +### Upsert records + +Upstash vector expects records inserted into indexes to have the following form: + +```typescript +type UpstashRecord = { + id: number | string; + vector: number[]; + metadata?: Record; +}; +``` + +To upsert some records, you can use the client like so: + +```typescript +const index = new Index(); + +// Prepare your data. The length of each array +// of vector values must match the dimension of +// the index where you plan to store them. +const records = [ + { + id: "1", + vector: [0.236, 0.971, 0.559], + }, + { + id: "2", + vector: [0.685, 0.111, 0.857], + }, +]; + +// Upsert the data into your index +await index.upsert(records); +``` + +### Querying + +#### Querying with vector values + +The query method accepts a large number of options. The dimension of the query vector must match the dimension of your index. + +```typescript +type QueryOptions = { + vector: number[]; + topK: number; + includeVectors?: boolean; + includeMetadata?: boolean; +}; +``` + +For example, to query by vector values you would pass the `vector` param in the options configuration. For brevity sake this example query vector is tiny (dimension 2), but in a more realistic use case this query vector would be an embedding outputted by a model. Look at the [Example code](#example-code) to see more realistic examples of how to use `query`. + +```typescript +> await index.query({ topK: 3, vector: [ 0.22, 0.66 ]}) +{ + matches: [ + { + id: '6345', + score: 1.00000012, + vector: [], + metadata: undefined + }, + { + id: '1233', + score: 1.00000012, + vector: [], + metadata: undefined + }, + { + id: '4142', + score: 1.00000012, + vector: [], + metadata: undefined + } + ], + namespace: '' +} +``` + +You include options to `includeMetadata: true` or `includeVectors: true` if you need this information. By default these are not returned to keep the response payload small. + +### Update a record + +You may want to update vector `vector` or `metadata`. Specify the id and the attribute value you want to update. + +```typescript +await index.upsert({ + id: "18593", + metadata: { genre: "romance" }, +}); +``` + +### Fetch records by their IDs + +```typescript +const fetchResult = await index.fetch(["id-1", "id-2"]); +``` + +### Delete records + +For convenience there are several delete-related options. You can verify the results of a delete operation by trying to `fetch()` a record. + +#### Delete one + +```typescript +await index.delete("id-to-delete"); +``` + +#### Delete many by id + +```typescript +await index.delete(["id-1", "id-2", "id-3"]); +``` diff --git a/index.ts b/index.ts index 17246f9..ce03e7e 100644 --- a/index.ts +++ b/index.ts @@ -13,7 +13,7 @@ export type { Requester, UpstashRequest, UpstashResponse }; * Connection credentials for upstash vector. * Get them from https://console.upstash.com/vector/ */ -export type VectorConfig = { +export type IndexConfig = { /** * UPSTASH_VECTOR_REST_URL */ @@ -39,13 +39,13 @@ export class Index extends core.Index { * * @example * ```typescript - * const vector = new Vector({ + * const index = new Index({ * url: "", * token: "", * }); * ``` */ - constructor(config: VectorConfig); + constructor(config: IndexConfig); /** * Create a new vector client by providing a custom `Requester` implementation @@ -65,7 +65,7 @@ export class Index extends core.Index { * ``` */ constructor(requesters: Requester); - constructor(configOrRequester: VectorConfig | Requester) { + constructor(configOrRequester: IndexConfig | Requester) { if ("request" in configOrRequester) { super(configOrRequester); return; @@ -109,7 +109,7 @@ export class Index extends core.Index { * This tries to load `UPSTASH_VECTOR_REST_URL` and `UPSTASH_VECTOR_REST_TOKEN` from * your environment using `process.env`. */ - static fromEnv(config?: Omit): Index { + static fromEnv(config?: Omit): Index { const url = process?.env.UPSTASH_VECTOR_REST_URL; if (!url) { throw new Error( diff --git a/package.json b/package.json index 8c0fdad..15648b6 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "module": "./dist/index.mjs", "main": "./dist/index.js", "types": "./dist/index.d.ts", - "version": "0.1.0", + "version": "v0.1.0-alpha", "keywords": [ "vector", "upstash", diff --git a/src/commands/client/delete/index.test.ts b/src/commands/client/delete/index.test.ts index 9182c8f..94688fc 100644 --- a/src/commands/client/delete/index.test.ts +++ b/src/commands/client/delete/index.test.ts @@ -16,7 +16,7 @@ describe("DELETE", () => { ); await Promise.all(upsertPromises); - const deletionResult = await new DeleteCommand({ ids: idsToUpsert }).exec(client); + const deletionResult = await new DeleteCommand(idsToUpsert).exec(client); expect(deletionResult).toBeTruthy(); }); @@ -29,8 +29,21 @@ describe("DELETE", () => { ); await Promise.all(upsertPromises); - await new DeleteCommand({ ids: idsToUpsert }).exec(client); - const res1 = await new DeleteCommand({ ids: idsToUpsert }).exec(client); - expect(res1).toBeNull(); + await new DeleteCommand(idsToUpsert).exec(client); + const res1 = await new DeleteCommand(idsToUpsert).exec(client); + expect(res1).toEqual({ + deleted: 0, + }); + }); + + test("should delete single item", async () => { + const initialVector = [6.6, 7.7]; + const id = randomID(); + await new UpsertCommand({ id, vector: initialVector }).exec(client); + + const res1 = await new DeleteCommand(id).exec(client); + expect(res1).toEqual({ + deleted: 1, + }); }); }); diff --git a/src/commands/client/delete/index.ts b/src/commands/client/delete/index.ts index cf6df95..9a960f6 100644 --- a/src/commands/client/delete/index.ts +++ b/src/commands/client/delete/index.ts @@ -1,34 +1,13 @@ import { Command } from "@commands/command"; -/** - * Payload Type Definition for DeleteCommand - * - * This type defines the structure of the payload specifically used in the DeleteCommand. - * - * Properties: - * - ids: An array of numbers or strings representing the unique identifiers of the records to be deleted. These could be database IDs, unique keys, or any identifier used to uniquely refer to records in a specific context. - * - * Usage: - * This type is typically used in scenarios where a batch deletion of records is required. The `ids` array allows specifying multiple records for deletion in a single command, thereby facilitating efficient bulk operations. - */ -type Payload = { - ids: number[] | string[]; -}; - -/** - * DeleteCommand Class - * - * This class extends the generic Command class to implement the deletion functionality. - * - * Example: - * ``` - * const deletionIds = [123, 456, 789]; - * const deleteCommand = new DeleteCommand({ ids: deletionIds }); - * // Use deleteCommand to execute the deletion operation - * ``` - */ -export class DeleteCommand extends Command { - constructor(payload: Payload) { - super(payload.ids, "delete"); +export class DeleteCommand extends Command<{ deleted: number }> { + constructor(id: (number[] | string[]) | number | string) { + const finalArr = []; + if (Array.isArray(id)) { + finalArr.push(...id); + } else { + finalArr.push(id); + } + super(finalArr, "delete"); } } diff --git a/src/commands/client/fetch/index.test.ts b/src/commands/client/fetch/index.test.ts index 092c4c8..75b0621 100644 --- a/src/commands/client/fetch/index.test.ts +++ b/src/commands/client/fetch/index.test.ts @@ -15,19 +15,23 @@ describe("FETCH", () => { const payloads = randomizedData.map((data) => new UpsertCommand(data).exec(client)); await Promise.all(payloads); - const res = await new FetchCommand({ - ids: randomizedData.map((x) => x.id), - includeVectors: true, - }).exec(client); + const res = await new FetchCommand([ + randomizedData.map((x) => x.id), + { + includeVectors: true, + }, + ]).exec(client); expect(res).toEqual(randomizedData); }); test("should return null when id does not exist", async () => { - const res = await new FetchCommand({ - ids: [randomID()], - includeVectors: true, - }).exec(client); + const res = await new FetchCommand([ + [randomID()], + { + includeVectors: true, + }, + ]).exec(client); expect(res).toEqual([null]); }); @@ -40,11 +44,13 @@ describe("FETCH", () => { }; await new UpsertCommand(mockData).exec(client); - const res = await new FetchCommand<{ hello: string }>({ - ids: [mockData.id], - includeVectors: true, - includeMetadata: true, - }).exec(client); + const res = await new FetchCommand<{ hello: string }>([ + [mockData.id], + { + includeVectors: true, + includeMetadata: true, + }, + ]).exec(client); expect(res).toEqual([mockData]); }); diff --git a/src/commands/client/fetch/index.ts b/src/commands/client/fetch/index.ts index ae6b26e..534b1b9 100644 --- a/src/commands/client/fetch/index.ts +++ b/src/commands/client/fetch/index.ts @@ -1,45 +1,15 @@ import { Command } from "@commands/command"; import { Vector } from "../types"; -/** - * Type definition for FetchCommand payload - * - * Properties: - * - ids: An array of numbers or strings, representing the unique identifiers of the records to be fetched. - * - includeMetadata (optional): A boolean flag indicating whether to include metadata in the response. - * - includeVectors (optional): A boolean flag indicating whether to include vector data in the response. - * - * The Payload type is used in the FetchCommand to specify the data required to fetch specific records. - * The optional flags allow for more detailed responses depending on the requirements. - */ -type Payload = { - ids: number[] | string[]; +type FetchCommandOptions = { includeMetadata?: boolean; includeVectors?: boolean; }; -/** - * Generic response type for FetchCommand - * - * This type represents the possible return type of a FetchCommand. It can be either a Vector - * containing metadata or null, depending on whether the fetch operation was successful or not. - */ -type FetchReturnResponse = Vector | null; +export type FetchReturnResponse = Vector | null; -/** - * FetchCommand Class - * - * Extends the generic Command class to implement a fetch operation. - * - * Example: - * ``` - * const fetchPayload = { ids: [1, 2, 3], includeMetadata: true }; - * const fetchCommand = new FetchCommand(fetchPayload); - * // Use fetchCommand to execute the fetch operation - * ``` - */ export class FetchCommand extends Command[]> { - constructor(payload: Payload) { - super({ ...payload }, "fetch"); + constructor([ids, opts]: [ids: number[] | string[], opts: FetchCommandOptions]) { + super({ ids, ...opts }, "fetch"); } } diff --git a/src/commands/client/query/index.test.ts b/src/commands/client/query/index.test.ts index e9059c9..781d7b0 100644 --- a/src/commands/client/query/index.test.ts +++ b/src/commands/client/query/index.test.ts @@ -15,7 +15,7 @@ describe("QUERY", () => { await new UpsertCommand(initialData).exec(client); //This is needed for vector index insertion to happen. When run with other tests in parallel this tends to fail without sleep. But, standalone it should work without an issue. await sleep(2000); - const res = await new QueryCommand({ + const res = await new QueryCommand<{ hello: "World" }>({ includeVectors: true, vector: initialVector, topK: 1, diff --git a/src/commands/client/query/index.ts b/src/commands/client/query/index.ts index 4e0827e..1ec218f 100644 --- a/src/commands/client/query/index.ts +++ b/src/commands/client/query/index.ts @@ -1,44 +1,21 @@ import { Command } from "@commands/command"; -/** - * Payload Type Definition - * - * This type defines the structure of the payload used in a specific function or API call. - * - * Properties: - * - vector: An array of numbers representing a specific vector. This could be coordinates, data points, or any numerical representation depending on the context of the function or API. - * - * - topK: A number indicating the 'top K' elements to be considered or returned. In many contexts, this refers to the top 'K' results, items, or entities based on certain criteria like highest score, most relevance, etc. - * - * - includeVectors: A boolean value indicating whether to include the vector data in the response or output. Setting this to 'true' includes the vector data. - * - * Usage: - * This type is typically used when sending or receiving data where a combination of a numerical vector, a limit on the number of elements to consider, and an option to include or exclude detailed vector data is required. - */ -type Payload = { +type QueryCommandPayload = { vector: number[]; topK: number; - includeVectors: boolean; + includeVectors?: boolean; + includeMetadata?: boolean; }; -type QueryReturnResponse = { +export type QueryReturnResponse = { id: number | string; score: number; vector: number[]; metadata?: TMetadata; }; -/** - * QueryCommand Class - * Example: - * ``` - * const payload = { vector: [1, 2, 3], topK: 5, includeVectors: true }; - * const queryCommand = new QueryCommand(payload); - * // Use queryCommand for further operations - * ``` - */ -export class QueryCommand extends Command[]> { - constructor(payload: Payload) { - super({ ...payload }, "query"); +export class QueryCommand extends Command[]> { + constructor(payload: QueryCommandPayload) { + super(payload, "query"); } } diff --git a/src/commands/client/range/index.ts b/src/commands/client/range/index.ts index 52accf8..6751a3a 100644 --- a/src/commands/client/range/index.ts +++ b/src/commands/client/range/index.ts @@ -1,55 +1,20 @@ import { Command } from "@commands/command"; import { Vector } from "../types"; -/** - * Type definition for RangeCommand payload - * - * This type specifies the structure of the payload used in the RangeCommand. - * - * Properties: - * - cursor: A number indicating the starting point for the range query. - * - limit: A number specifying the maximum number of records to be returned. - * - includeVectors (optional): A boolean flag indicating whether to include vector data in the response. - * - includeMetadata (optional): A boolean flag indicating whether to include metadata in the response. - * - * This payload type is used for range queries, where a set of records is retrieved based on the specified cursor - * and limit. The optional inclusion of vectors and metadata allows for flexible and detailed data retrieval. - */ -type Payload = { - cursor: number; +type RangeCommandPayload = { + cursor: number | string; limit: number; includeVectors?: boolean; includeMetadata?: boolean; }; -/** - * Type definition for the response returned by RangeCommand - * - * This type outlines the structure of the response from a RangeCommand. - * - * Properties: - * - nextCursor: A string that indicates the cursor to be used for the next range query, facilitating pagination. - * - vectors: An array of Vector objects, each containing TMetadata, representing the data retrieved in the range query. - * - * The RangeReturnResponse type is crucial for operations that involve retrieving a range of records, - * providing both the data (in the form of vectors) and the means to continue fetching subsequent ranges (via nextCursor). - */ -type RangeReturnResponse = { +export type RangeReturnResponse = { nextCursor: string; vectors: Vector[]; }; -/** - * RangeCommand Class - * Example: - * ``` - * const rangePayload = { cursor: 0, limit: 10, includeVectors: true }; - * const rangeCommand = new RangeCommand(rangePayload); - * // Use rangeCommand to execute the range query and retrieve data - * ``` - */ -export class RangeCommand extends Command> { - constructor(payload: Payload) { +export class RangeCommand extends Command> { + constructor(payload: RangeCommandPayload) { super(payload, "range"); } } diff --git a/src/commands/client/reset/index.test.ts b/src/commands/client/reset/index.test.ts index 24e8d2b..a81d107 100644 --- a/src/commands/client/reset/index.test.ts +++ b/src/commands/client/reset/index.test.ts @@ -14,18 +14,22 @@ describe("RESET", () => { await Promise.all(payloads); - const res = await new FetchCommand({ - ids: randomizedData.map((x) => x.id), - includeVectors: true, - }).exec(client); + const res = await new FetchCommand([ + randomizedData.map((x) => x.id), + { + includeVectors: true, + }, + ]).exec(client); expect(res).toEqual(randomizedData); await new ResetCommand().exec(client); - const resAfterReset = await new FetchCommand({ - ids: randomizedData.map((x) => x.id), - includeVectors: true, - }).exec(client); + const resAfterReset = await new FetchCommand([ + randomizedData.map((x) => x.id), + { + includeVectors: true, + }, + ]).exec(client); expect(resAfterReset).toEqual(new Array(20).fill(null)); }); diff --git a/src/commands/client/reset/index.ts b/src/commands/client/reset/index.ts index 34362cc..2196e6c 100644 --- a/src/commands/client/reset/index.ts +++ b/src/commands/client/reset/index.ts @@ -1,12 +1,5 @@ import { Command } from "@commands/command"; -/** - * Example: - * ``` - * const resetCommand = new ResetCommand(); - * // Use resetCommand to execute the reset operation - * ``` - */ export class ResetCommand extends Command { constructor() { super([], "reset"); diff --git a/src/commands/client/upsert/index.test.ts b/src/commands/client/upsert/index.test.ts index 4a9a114..653c786 100644 --- a/src/commands/client/upsert/index.test.ts +++ b/src/commands/client/upsert/index.test.ts @@ -26,8 +26,25 @@ describe("UPSERT", () => { const res = await new UpsertCommand({ id: 1, vector: [0.1, 0.2], - metadata: { upstash: test }, + metadata: { upstash: "test" }, }).exec(client); expect(res).toEqual("Success"); }); + + test("should add bulk data with string id", async () => { + //@ts-ignore + const res = await new UpsertCommand([ + { + id: "hello-world", + vector: [0.1, 0.2], + metadata: { upstash: "test" }, + }, + { + id: "hello-world-4", + vector: [3, 4], + metadata: { upstash: "test" }, + }, + ]).exec(client); + expect(res).toEqual("Success"); + }); }); diff --git a/src/commands/client/upsert/index.ts b/src/commands/client/upsert/index.ts index ee968e2..a320c61 100644 --- a/src/commands/client/upsert/index.ts +++ b/src/commands/client/upsert/index.ts @@ -1,40 +1,13 @@ import { Command } from "@commands/command"; -/** - * Payload Type Definition for UpsertCommand - * - * This type defines the structure of the payload used in the UpsertCommand. - * - * Properties: - * - id: A number or string representing the unique identifier of the record to be upserted (inserted or updated). - * - vector: An array of numbers representing a specific vector. This could be coordinates, data points, or any numerical representation depending on the context. - * - metadata (optional): An object with key-value pairs, where the keys are strings and the values are of unknown type. This allows for flexible and additional data to be associated with the record being upserted. - * - * Usage: - * This type is primarily used in scenarios where a record needs to be inserted into a database if it does not already exist, or updated if it does. The flexibility of the metadata field allows for various additional information to be passed along with the primary data. - */ -type Payload = { +type UpsertCommandPayload = { id: number | string; vector: number[]; metadata?: Record; }; -/** - * UpsertCommand Class - * - * Extends the generic Command class to implement an upsert (insert or update) operation. - * - * Example: - * ``` - * const upsertPayload = { id: 123, vector: [1.1, 2.2, 3.3], metadata: { key: "value" } }; - * const upsertCommand = new UpsertCommand(upsertPayload); - * // Use upsertCommand to execute the upsert operation - * ``` - * - * The UpsertCommand takes a payload containing the necessary data for the upsert operation. It supports handling both insertion and update of records based on the provided identifier. - */ export class UpsertCommand extends Command { - constructor(payload: Payload) { - super({ ...payload }, "upsert"); + constructor(payload: UpsertCommandPayload | UpsertCommandPayload[]) { + super(payload, "upsert"); } } diff --git a/src/http/index.ts b/src/http/index.ts index a2ecf89..a652d7d 100644 --- a/src/http/index.ts +++ b/src/http/index.ts @@ -20,13 +20,6 @@ export type UpstashResponse = { error?: string; }; -export type RawUpstashResponse = - | { - result?: string; - error?: string; - } - | TResult; - export interface Requester { request: (req: UpstashRequest) => Promise>; } @@ -146,20 +139,11 @@ export class HttpClient implements Requester { throw error ?? new Error("Exhausted all retries"); } - const body = (await res.json()) as RawUpstashResponse; - if (isResultErrorTuple(body)) { - if (!res.ok) { - throw new UpstashError(`${body.error}, command was: ${JSON.stringify(req.body)}`); - } - - return body as UpstashResponse; + const body = (await res.json()) as UpstashResponse; + if (!res.ok) { + throw new UpstashError(`${body.error}, command was: ${JSON.stringify(req.body)}`); } - return { result: body }; - } -} -function isResultErrorTuple( - response: RawUpstashResponse -): response is { result?: string; error?: string } { - return response && typeof response === "object" && ("result" in response || "error" in response); + return { result: body.result, error: body.error }; + } } diff --git a/src/vector.ts b/src/vector.ts index e66b9f8..7a761fa 100644 --- a/src/vector.ts +++ b/src/vector.ts @@ -32,10 +32,120 @@ export class Index { this.client = client; } + /** + * Deletes a specific item or items from the index by their ID(s). * + * + * @example + * ```js + * await index.delete('test-id') + * ``` + * + * @param id - List of ids or single id + * @returns A promise that resolves when the request to delete the index is completed. + */ delete = (args: CommandArgs) => new DeleteCommand(args).exec(this.client); + + /** + * Queries an index with specified parameters. + * This method creates and executes a query command on an index based on the provided arguments. + * + * @example + * ```js + * await index.query({ topK: 3, vector: [ 0.22, 0.66 ]}) + * ``` + * + * @param {Object} args - The arguments for the query command. + * @param {number[]} args.vector - An array of numbers representing the feature vector for the query. + * This vector is utilized to find the most relevant items in the index. + * @param {number} args.topK - The desired number of top results to be returned, based on relevance or similarity to the query vector. + * @param {boolean} [args.includeVectors=false] - When set to true, includes the feature vectors of the returned items in the response. + * @param {boolean} [args.includeMetadata=false] - When set to true, includes additional metadata of the returned items in the response. + * + * @returns A promise that resolves with an array of query result objects when the request to query the index is completed. + */ query = (args: CommandArgs) => new QueryCommand(args).exec(this.client); + + /** + * Upserts (Updates and Inserts) specific items into the index. + * It's used for adding new items to the index or updating existing ones. + * + * @example + * ```js + * const upsertArgs = { + * id: '123', + * vector: [0.42, 0.87, ...], + * metadata: { property1: 'value1', property2: 'value2' } + * }; + * const upsertResult = await index.upsert(upsertArgs); + * console.log(upsertResult); // Outputs the result of the upsert operation + * ``` + * + * @param {CommandArgs} args - The arguments for the upsert command. + * @param {number|string} args.id - The unique identifier for the item being upserted. + * @param {number[]} args.vector - The feature vector associated with the item. + * @param {Record} [args.metadata] - Optional metadata to be associated with the item. + * + * @returns {string} A promise that resolves with the result of the upsert operation after the command is executed. + */ upsert = (args: CommandArgs) => new UpsertCommand(args).exec(this.client); - fetch = (args: CommandArgs) => new FetchCommand(args).exec(this.client); + + /** + * It's used for retrieving specific items from the index, optionally including + * their metadata and feature vectors. + * + * @example + * ```js + * const fetchIds = ['123', '456']; + * const fetchOptions = { includeMetadata: true, includeVectors: false }; + * const fetchResults = await index.fetch(fetchIds, fetchOptions); + * console.log(fetchResults); // Outputs the fetched items + * ``` + * + * @param {...CommandArgs} args - The arguments for the fetch command. + * @param {(number[]|string[])} args[0] - An array of IDs of the items to be fetched. + * @param {FetchCommandOptions} args[1] - Options for the fetch operation. + * @param {boolean} [args[1].includeMetadata=false] - Optionally include metadata of the fetched items. + * @param {boolean} [args[1].includeVectors=false] - Optionally include feature vectors of the fetched items. + * + * @returns {Promise[]>} A promise that resolves with an array of fetched items or null if not found, after the command is executed. + */ + fetch = (...args: CommandArgs) => new FetchCommand(args).exec(this.client); + + /** + * It's used for wiping an entire index. + * + * @example + * ```js + * await index.reset(); + * console.log('Index has been reset'); + * ``` + * + * @returns {Promise} A promise that resolves with the result of the reset operation after the command is executed. + */ reset = () => new ResetCommand().exec(this.client); + + /** + * Retrieves a range of items from the index. + * + * @example + * ```js + * const rangeArgs = { + * cursor: 0, + * limit: 10, + * includeVectors: true, + * includeMetadata: false + * }; + * const rangeResults = await index.range(rangeArgs); + * console.log(rangeResults); // Outputs the result of the range operation + * ``` + * + * @param {CommandArgs} args - The arguments for the range command. + * @param {number|string} args.cursor - The starting point (cursor) for the range query. + * @param {number} args.limit - The maximum number of items to return in this range. + * @param {boolean} [args.includeVectors=false] - Optionally include the feature vectors of the items in the response. + * @param {boolean} [args.includeMetadata=false] - Optionally include additional metadata of the items in the response. + * + * @returns {Promise>} A promise that resolves with the response containing the next cursor and an array of vectors, after the command is executed. + */ range = (args: CommandArgs) => new RangeCommand(args).exec(this.client); }