forked from valkey-io/valkey-glide
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Node: add
FT.CREATE
command (valkey-io#2501)
* Add FT.CREATE command for Node Signed-off-by: Andrew Carbonetto <[email protected]> --------- Signed-off-by: Andrew Carbonetto <[email protected]> Signed-off-by: BoazBD <[email protected]>
- Loading branch information
1 parent
78a95b9
commit 98f63a2
Showing
8 changed files
with
748 additions
and
210 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
/** | ||
* Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { Decoder, DecoderOption, GlideString } from "../BaseClient"; | ||
import { GlideClient } from "../GlideClient"; | ||
import { GlideClusterClient } from "../GlideClusterClient"; | ||
import { Field, FtCreateOptions } from "./GlideFtOptions"; | ||
|
||
/** Module for Vector Search commands */ | ||
export class GlideFt { | ||
/** | ||
* Creates an index and initiates a backfill of that index. | ||
* | ||
* @param client The client to execute the command. | ||
* @param indexName The index name for the index to be created. | ||
* @param schema The fields of the index schema, specifying the fields and their types. | ||
* @param options Optional arguments for the `FT.CREATE` command. See {@link FtCreateOptions}. | ||
* | ||
* @returns If the index is successfully created, returns "OK". | ||
* | ||
* @example | ||
* ```typescript | ||
* // Example usage of FT.CREATE to create a 6-dimensional JSON index using the HNSW algorithm | ||
* await GlideFt.create(client, "json_idx1", [{ | ||
* type: "VECTOR", | ||
* name: "$.vec", | ||
* alias: "VEC", | ||
* attributes: { | ||
* algorithm: "HNSW", | ||
* type: "FLOAT32", | ||
* dimension: 6, | ||
* distanceMetric: "L2", | ||
* numberOfEdges: 32, | ||
* }, | ||
* }], { | ||
* dataType: "JSON", | ||
* prefixes: ["json:"] | ||
* }); | ||
* ``` | ||
*/ | ||
static async create( | ||
client: GlideClient | GlideClusterClient, | ||
indexName: GlideString, | ||
schema: Field[], | ||
options?: FtCreateOptions, | ||
): Promise<"OK"> { | ||
const args: GlideString[] = ["FT.CREATE", indexName]; | ||
|
||
if (options) { | ||
if ("dataType" in options) { | ||
args.push("ON", options.dataType); | ||
} | ||
|
||
if ("prefixes" in options && options.prefixes) { | ||
args.push( | ||
"PREFIX", | ||
options.prefixes.length.toString(), | ||
...options.prefixes, | ||
); | ||
} | ||
} | ||
|
||
args.push("SCHEMA"); | ||
|
||
schema.forEach((f) => { | ||
args.push(f.name); | ||
|
||
if (f.alias) { | ||
args.push("AS", f.alias); | ||
} | ||
|
||
args.push(f.type); | ||
|
||
switch (f.type) { | ||
case "TAG": { | ||
if (f.separator) { | ||
args.push("SEPARATOR", f.separator); | ||
} | ||
|
||
if (f.caseSensitive) { | ||
args.push("CASESENSITIVE"); | ||
} | ||
|
||
break; | ||
} | ||
|
||
case "VECTOR": { | ||
if (f.attributes) { | ||
args.push(f.attributes.algorithm); | ||
|
||
const attributes: GlideString[] = []; | ||
|
||
// all VectorFieldAttributes attributes | ||
if (f.attributes.dimension) { | ||
attributes.push( | ||
"DIM", | ||
f.attributes.dimension.toString(), | ||
); | ||
} | ||
|
||
if (f.attributes.distanceMetric) { | ||
attributes.push( | ||
"DISTANCE_METRIC", | ||
f.attributes.distanceMetric.toString(), | ||
); | ||
} | ||
|
||
if (f.attributes.type) { | ||
attributes.push( | ||
"TYPE", | ||
f.attributes.type.toString(), | ||
); | ||
} | ||
|
||
if (f.attributes.initialCap) { | ||
attributes.push( | ||
"INITIAL_CAP", | ||
f.attributes.initialCap.toString(), | ||
); | ||
} | ||
|
||
// VectorFieldAttributesHnsw attributes | ||
if ("m" in f.attributes && f.attributes.m) { | ||
attributes.push("M", f.attributes.m.toString()); | ||
} | ||
|
||
if ( | ||
"efContruction" in f.attributes && | ||
f.attributes.efContruction | ||
) { | ||
attributes.push( | ||
"EF_CONSTRUCTION", | ||
f.attributes.efContruction.toString(), | ||
); | ||
} | ||
|
||
if ( | ||
"efRuntime" in f.attributes && | ||
f.attributes.efRuntime | ||
) { | ||
attributes.push( | ||
"EF_RUNTIME", | ||
f.attributes.efRuntime.toString(), | ||
); | ||
} | ||
|
||
args.push(attributes.length.toString(), ...attributes); | ||
} | ||
|
||
break; | ||
} | ||
|
||
default: | ||
// no-op | ||
} | ||
}); | ||
|
||
return _handleCustomCommand(client, args, { | ||
decoder: Decoder.String, | ||
}) as Promise<"OK">; | ||
} | ||
} | ||
|
||
/** | ||
* @internal | ||
*/ | ||
function _handleCustomCommand( | ||
client: GlideClient | GlideClusterClient, | ||
args: GlideString[], | ||
decoderOption: DecoderOption, | ||
) { | ||
return client instanceof GlideClient | ||
? (client as GlideClient).customCommand(args, decoderOption) | ||
: (client as GlideClusterClient).customCommand(args, decoderOption); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
/** | ||
* Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { GlideString } from "../BaseClient"; | ||
|
||
interface BaseField { | ||
/** The name of the field. */ | ||
name: GlideString; | ||
/** An alias for field. */ | ||
alias?: GlideString; | ||
} | ||
|
||
/** | ||
* Field contains any blob of data. | ||
*/ | ||
export type TextField = BaseField & { | ||
/** Field identifier */ | ||
type: "TEXT"; | ||
}; | ||
|
||
/** | ||
* Tag fields are similar to full-text fields, but they interpret the text as a simple list of | ||
* tags delimited by a separator character. | ||
* | ||
* For HASH fields, separator default is a comma (`,`). For JSON fields, there is no default | ||
* separator; you must declare one explicitly if needed. | ||
*/ | ||
export type TagField = BaseField & { | ||
/** Field identifier */ | ||
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. */ | ||
caseSensitive?: boolean; | ||
}; | ||
|
||
/** | ||
* Field contains a number. | ||
*/ | ||
export type NumericField = BaseField & { | ||
/** Field identifier */ | ||
type: "NUMERIC"; | ||
}; | ||
|
||
/** | ||
* Superclass for vector field implementations, contains common logic. | ||
*/ | ||
export type VectorField = BaseField & { | ||
/** Field identifier */ | ||
type: "VECTOR"; | ||
/** Additional attributes to be passed with the vector field after the algorithm name. */ | ||
attributes: VectorFieldAttributesFlat | VectorFieldAttributesHnsw; | ||
}; | ||
|
||
/** | ||
* 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; | ||
/** | ||
* The distance metric used in vector type field. Can be one of [L2 | IP | COSINE]. | ||
*/ | ||
distanceMetric: "L2" | "IP" | "COSINE"; | ||
/** Vector type. The only supported type is FLOAT32. */ | ||
type: "FLOAT32"; | ||
/** | ||
* Initial vector capacity in the index affecting memory allocation size of the index. Defaults to 1024. | ||
*/ | ||
initialCap?: number; | ||
} | ||
|
||
/** | ||
* Vector field that supports vector search by FLAT (brute force) algorithm. | ||
* | ||
* The algorithm is a brute force linear processing of each vector in the index, yielding exact | ||
* answers within the bounds of the precision of the distance computations. | ||
*/ | ||
export type VectorFieldAttributesFlat = VectorFieldAttributes & { | ||
algorithm: "FLAT"; | ||
}; | ||
|
||
/** | ||
* Vector field that supports vector search by HNSM (Hierarchical Navigable Small World) algorithm. | ||
* | ||
* The algorithm provides an approximation of the correct answer in exchange for substantially | ||
* lower execution times. | ||
*/ | ||
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. | ||
*/ | ||
numberOfEdges?: number; | ||
/** | ||
* Controls the number of vectors examined during index construction. Default value is 200, Maximum value is 4096. | ||
* Equivalent to the `efContruction` attribute. | ||
*/ | ||
vectorsExaminedOnConstruction?: number; | ||
/** | ||
* Controls the number of vectors examined during query operations. Default value is 10, Maximum value is 4096. | ||
* Equivalent to the `efRuntime` attribute. | ||
*/ | ||
vectorsExaminedOnRuntime?: number; | ||
}; | ||
|
||
export type Field = TextField | TagField | NumericField | VectorField; | ||
|
||
/** | ||
* Represents the input options to be used in the FT.CREATE command. | ||
* All fields in this class are optional inputs for FT.CREATE. | ||
*/ | ||
export interface FtCreateOptions { | ||
/** The type of data to be indexed using FT.CREATE. */ | ||
dataType: "JSON" | "HASH"; | ||
/** The prefix of the key to be indexed. */ | ||
prefixes?: GlideString[]; | ||
} |
Oops, something went wrong.