diff --git a/java/client/src/main/java/glide/api/commands/servermodules/FT.java b/java/client/src/main/java/glide/api/commands/servermodules/FT.java index 714e1c1109..0250865648 100644 --- a/java/client/src/main/java/glide/api/commands/servermodules/FT.java +++ b/java/client/src/main/java/glide/api/commands/servermodules/FT.java @@ -285,6 +285,7 @@ public static CompletableFuture search( /** * Deletes an index and associated content. Indexed document keys are unaffected. * + * @param client The client to execute the command. * @param indexName The index name. * @return "OK". * @example @@ -300,6 +301,7 @@ public static CompletableFuture dropindex( /** * Deletes an index and associated content. Indexed document keys are unaffected. * + * @param client The client to execute the command. * @param indexName The index name. * @return "OK". * @example diff --git a/node/src/server-modules/GlideFt.ts b/node/src/server-modules/GlideFt.ts index 566e4d54c4..e78f961c8c 100644 --- a/node/src/server-modules/GlideFt.ts +++ b/node/src/server-modules/GlideFt.ts @@ -92,10 +92,10 @@ export class GlideFt { const attributes: GlideString[] = []; // all VectorFieldAttributes attributes - if (f.attributes.dimension) { + if (f.attributes.dimensions) { attributes.push( "DIM", - f.attributes.dimension.toString(), + f.attributes.dimensions.toString(), ); } @@ -111,6 +111,8 @@ export class GlideFt { "TYPE", f.attributes.type.toString(), ); + } else { + attributes.push("TYPE", "FLOAT32"); } if (f.attributes.initialCap) { @@ -160,6 +162,31 @@ export class GlideFt { decoder: Decoder.String, }) as Promise<"OK">; } + + /** + * Deletes an index and associated content. Indexed document keys are unaffected. + * + * @param client The client to execute the command. + * @param indexName The index name. + * + * @returns "OK" + * + * @example + * ```typescript + * // Example usage of FT.DROPINDEX to drop an index + * await GlideFt.dropindex(client, "json_idx1"); // "OK" + * ``` + */ + static async dropindex( + client: GlideClient | GlideClusterClient, + indexName: GlideString, + ): Promise<"OK"> { + const args: GlideString[] = ["FT.DROPINDEX", indexName]; + + return _handleCustomCommand(client, args, { + decoder: Decoder.String, + }) as Promise<"OK">; + } } /** diff --git a/node/src/server-modules/GlideFtOptions.ts b/node/src/server-modules/GlideFtOptions.ts index 6fe723cc9d..c4cff5883b 100644 --- a/node/src/server-modules/GlideFtOptions.ts +++ b/node/src/server-modules/GlideFtOptions.ts @@ -31,7 +31,7 @@ export type TagField = BaseField & { type: "TAG"; /** Specify how text in the attribute is split into individual tags. Must be a single character. */ separator?: GlideString; - /** Preserve the original letter cases of tags. If set to False, characters are converted to lowercase by default. */ + /** Preserve the original letter cases of tags. If set to `False`, characters are converted to lowercase by default. */ caseSensitive?: boolean; }; @@ -57,16 +57,16 @@ export type VectorField = BaseField & { * Base class for defining vector field attributes to be used after the vector algorithm name. */ export interface VectorFieldAttributes { - /** Number of dimensions in the vector. Equivalent to DIM in the option. */ - dimension: number; + /** Number of dimensions in the vector. Equivalent to `DIM` in the module API. */ + dimensions: number; /** - * The distance metric used in vector type field. Can be one of [L2 | IP | COSINE]. + * The distance metric used in vector type field. Can be one of `[L2 | IP | COSINE]`. Equivalent to `DISTANCE_METRIC` in the module API. */ distanceMetric: "L2" | "IP" | "COSINE"; /** Vector type. The only supported type is FLOAT32. */ - type: "FLOAT32"; + type?: "FLOAT32"; /** - * Initial vector capacity in the index affecting memory allocation size of the index. Defaults to 1024. + * Initial vector capacity in the index affecting memory allocation size of the index. Defaults to `1024`. Equivalent to `INITIAL_CAP` in the module API. */ initialCap?: number; } @@ -90,18 +90,18 @@ export type VectorFieldAttributesFlat = VectorFieldAttributes & { export type VectorFieldAttributesHnsw = VectorFieldAttributes & { algorithm: "HNSW"; /** - * Number of maximum allowed outgoing edges for each node in the graph in each layer. Default is 16, maximum is 512. - * Equivalent to the `m` attribute. + * Number of maximum allowed outgoing edges for each node in the graph in each layer. Default is `16`, maximum is `512`. + * Equivalent to `M` in the module API. */ numberOfEdges?: number; /** - * Controls the number of vectors examined during index construction. Default value is 200, Maximum value is 4096. - * Equivalent to the `efContruction` attribute. + * Controls the number of vectors examined during index construction. Default value is `200`, Maximum value is `4096`. + * Equivalent to `EF_CONSTRUCTION` in the module API. */ vectorsExaminedOnConstruction?: number; /** - * Controls the number of vectors examined during query operations. Default value is 10, Maximum value is 4096. - * Equivalent to the `efRuntime` attribute. + * Controls the number of vectors examined during query operations. Default value is `10`, Maximum value is `4096`. + * Equivalent to `EF_RUNTIME` in the module API. */ vectorsExaminedOnRuntime?: number; }; diff --git a/node/tests/ServerModules.test.ts b/node/tests/ServerModules.test.ts index 29e10bcfaf..aa075e42ec 100644 --- a/node/tests/ServerModules.test.ts +++ b/node/tests/ServerModules.test.ts @@ -629,7 +629,7 @@ describe("Server Module Tests", () => { attributes: { algorithm: "HNSW", type: "FLOAT32", - dimension: 2, + dimensions: 2, distanceMetric: "L2", }, }; @@ -649,7 +649,7 @@ describe("Server Module Tests", () => { attributes: { algorithm: "HNSW", type: "FLOAT32", - dimension: 6, + dimensions: 6, distanceMetric: "L2", numberOfEdges: 32, }, @@ -669,7 +669,7 @@ describe("Server Module Tests", () => { attributes: { algorithm: "FLAT", type: "FLOAT32", - dimension: 6, + dimensions: 6, distanceMetric: "L2", }, }; @@ -684,7 +684,7 @@ describe("Server Module Tests", () => { attributes: { algorithm: "HNSW", type: "FLOAT32", - dimension: 1536, + dimensions: 1536, distanceMetric: "COSINE", numberOfEdges: 40, vectorsExaminedOnConstruction: 250, @@ -766,5 +766,50 @@ describe("Server Module Tests", () => { expect((e as Error).message).toContain("already exists"); } }); + + it("Ft.DROPINDEX test", async () => { + client = await GlideClusterClient.createClient( + getClientConfigurationOption( + cluster.getAddresses(), + ProtocolVersion.RESP3, + ), + ); + + // create an index + const index = uuidv4(); + expect( + await GlideFt.create(client, index, [ + { + type: "VECTOR", + name: "vec", + attributes: { + algorithm: "HNSW", + distanceMetric: "L2", + dimensions: 2, + }, + }, + { type: "NUMERIC", name: "published_at" }, + { type: "TAG", name: "category" }, + ]), + ).toEqual("OK"); + + const before = await client.customCommand(["FT_LIST"]); + expect(before).toContain(index); + + // DROP it + expect(await GlideFt.dropindex(client, index)).toEqual("OK"); + + const after = await client.customCommand(["FT_LIST"]); + expect(after).not.toContain(index); + + // dropping the index again results in an error + try { + expect( + await GlideFt.dropindex(client, index), + ).rejects.toThrow(); + } catch (e) { + expect((e as Error).message).toContain("Index does not exist"); + } + }); }); });