Skip to content

Commit

Permalink
Add stats api
Browse files Browse the repository at this point in the history
  • Loading branch information
ogzhanolguncu committed Jan 17, 2024
1 parent d46ff6a commit 86c38d2
Show file tree
Hide file tree
Showing 13 changed files with 112 additions and 14 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ type UpstashRecord = {
};
```

#### Upsert many

To upsert some records, you can use the client like so:

```typescript
Expand All @@ -141,6 +143,22 @@ const records = [
await index.upsert(records);
```

#### Upsert one

```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 record = {
id: "1",
vector: [0.236, 0.971, 0.559],
};
// Upsert the data into your index
await index.upsert(record);
```

### Querying

#### Querying with vector values
Expand Down Expand Up @@ -219,3 +237,11 @@ await index.delete("id-to-delete");
```typescript
await index.delete(["id-1", "id-2", "id-3"]);
```

### Stats

To get statistics of your index, you can use the client like so:

```typescript
await index.stats(["id-1", "id-2", "id-3"]);
```
2 changes: 2 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
} from "@http";
import * as core from "./src/vector";

export type * from "@commands/types";

export type { Requester, UpstashRequest, UpstashResponse };

/**
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"module": "./dist/index.mjs",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"version": "v0.1.0-alpha",
"version": "v0.1.0-alpha-9",
"keywords": [
"vector",
"upstash",
Expand Down
4 changes: 2 additions & 2 deletions src/commands/client/fetch/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ type FetchCommandOptions = {
includeVectors?: boolean;
};

export type FetchReturnResponse<TMetadata> = Vector<TMetadata> | null;
export type FetchResult<TMetadata = Record<string, unknown>> = Vector<TMetadata> | null;

export class FetchCommand<TMetadata> extends Command<FetchReturnResponse<TMetadata>[]> {
export class FetchCommand<TMetadata> extends Command<FetchResult<TMetadata>[]> {
constructor([ids, opts]: [ids: number[] | string[], opts: FetchCommandOptions]) {
super({ ids, ...opts }, "fetch");
}
Expand Down
4 changes: 2 additions & 2 deletions src/commands/client/query/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ type QueryCommandPayload = {
includeMetadata?: boolean;
};

export type QueryReturnResponse<TMetadata> = {
export type QueryResult<TMetadata = Record<string, unknown>> = {
id: number | string;
score: number;
vector: number[];
metadata?: TMetadata;
};

export class QueryCommand<TMetadata> extends Command<QueryReturnResponse<TMetadata>[]> {
export class QueryCommand<TMetadata> extends Command<QueryResult<TMetadata>[]> {
constructor(payload: QueryCommandPayload) {
super(payload, "query");
}
Expand Down
4 changes: 2 additions & 2 deletions src/commands/client/range/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ type RangeCommandPayload = {
includeMetadata?: boolean;
};

export type RangeReturnResponse<TMetadata> = {
export type RangeResult<TMetadata = Record<string, unknown>> = {
nextCursor: string;
vectors: Vector<TMetadata>[];
};

export class RangeCommand<TMetadata> extends Command<RangeReturnResponse<TMetadata>> {
export class RangeCommand<TMetadata> extends Command<RangeResult<TMetadata>> {
constructor(payload: RangeCommandPayload) {
super(payload, "range");
}
Expand Down
32 changes: 32 additions & 0 deletions src/commands/client/stats/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { afterAll, describe, expect, test } from "bun:test";
import { UpsertCommand } from "@commands/index";
import {
newHttpClient,
randomFloat,
randomID,
resetIndexes,
} from "@utils/test-utils";
import { sleep } from "bun";
import { StatsCommand } from ".";

const client = newHttpClient();

describe("STATS", () => {
afterAll(async () => await resetIndexes());

test("should return vectorCount successfully", async () => {
const vectorCount = 20;
const randomizedData = new Array(vectorCount).fill("").map(() => ({
id: randomID(),
vector: [randomFloat(), randomFloat()],
}));

const payloads = randomizedData.map((data) =>
new UpsertCommand(data).exec(client)
);
await Promise.all(payloads);
await sleep(2000);
const res = await new StatsCommand().exec(client);
expect(res.vectorCount).toBeGreaterThanOrEqual(vectorCount);
});
});
13 changes: 13 additions & 0 deletions src/commands/client/stats/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Command } from "@commands/command";

export type StatsResult = {
vectorCount: number;
pendingVectorCount: number;
indexSize: number;
};

export class StatsCommand extends Command<StatsResult> {
constructor() {
super([], "stats");
}
}
2 changes: 1 addition & 1 deletion src/commands/client/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type Vector<TMetadata> = {
export type Vector<TMetadata = Record<string, unknown>> = {
id: string;
vector: number[];
metadata?: TMetadata;
Expand Down
2 changes: 1 addition & 1 deletion src/commands/command.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { UpstashError } from "@error/index";
import { Requester } from "@http";

const ENDPOINTS = ["upsert", "query", "delete", "fetch", "reset", "range"] as const;
const ENDPOINTS = ["upsert", "query", "delete", "fetch", "reset", "range", "stats"] as const;

export type EndpointVariants = (typeof ENDPOINTS)[number];
/**
Expand Down
1 change: 1 addition & 0 deletions src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from "./client/query";
export * from "./client/upsert";
export * from "./client/reset";
export * from "./client/range";
export * from "./client/stats";
5 changes: 5 additions & 0 deletions src/commands/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export { type Vector } from "./client/types";
export { type RangeResult } from "./client/range/index";
export { type FetchResult } from "./client/fetch/index";
export { type QueryResult } from "./client/query/index";
export { type StatsResult } from "./client/stats/index";
29 changes: 24 additions & 5 deletions src/vector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
UpsertCommand,
} from "@commands/client";
import { Requester } from "@http";
import { StatsCommand } from "./commands";

export type CommandArgs<TCommand extends new (_args: any) => any> =
ConstructorParameters<TCommand>[0];
Expand Down Expand Up @@ -43,7 +44,8 @@ export class Index {
* @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<typeof DeleteCommand>) => new DeleteCommand(args).exec(this.client);
delete = (args: CommandArgs<typeof DeleteCommand>) =>
new DeleteCommand(args).exec(this.client);

/**
* Queries an index with specified parameters.
Expand All @@ -63,7 +65,8 @@ export class Index {
*
* @returns A promise that resolves with an array of query result objects when the request to query the index is completed.
*/
query = (args: CommandArgs<typeof QueryCommand>) => new QueryCommand(args).exec(this.client);
query = (args: CommandArgs<typeof QueryCommand>) =>
new QueryCommand(args).exec(this.client);

/**
* Upserts (Updates and Inserts) specific items into the index.
Expand All @@ -87,7 +90,8 @@ export class Index {
*
* @returns {string} A promise that resolves with the result of the upsert operation after the command is executed.
*/
upsert = (args: CommandArgs<typeof UpsertCommand>) => new UpsertCommand(args).exec(this.client);
upsert = (args: CommandArgs<typeof UpsertCommand>) =>
new UpsertCommand(args).exec(this.client);

/**
* It's used for retrieving specific items from the index, optionally including
Expand All @@ -109,7 +113,8 @@ export class Index {
*
* @returns {Promise<FetchReturnResponse<TMetadata>[]>} A promise that resolves with an array of fetched items or null if not found, after the command is executed.
*/
fetch = (...args: CommandArgs<typeof FetchCommand>) => new FetchCommand(args).exec(this.client);
fetch = (...args: CommandArgs<typeof FetchCommand>) =>
new FetchCommand(args).exec(this.client);

/**
* It's used for wiping an entire index.
Expand Down Expand Up @@ -147,5 +152,19 @@ export class Index {
*
* @returns {Promise<RangeReturnResponse<TMetadata>>} A promise that resolves with the response containing the next cursor and an array of vectors, after the command is executed.
*/
range = (args: CommandArgs<typeof RangeCommand>) => new RangeCommand(args).exec(this.client);
range = (args: CommandArgs<typeof RangeCommand>) =>
new RangeCommand(args).exec(this.client);

/**
* Retrieves stats from the index.
*
* @example
* ```js
* const statResults = await index.stats();
* console.log(statResults); // Outputs the result of the stats operation
* ```
*
* @returns {Promise<RangeReturnResponse<TMetadata>>} A promise that resolves with the response containing the vectorCount, pendingVectorCount, indexSize after the command is executed.
*/
stats = () => new StatsCommand().exec(this.client);
}

0 comments on commit 86c38d2

Please sign in to comment.