redis-vl 0.1.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +212 -0
  3. package/dist/errors.d.ts +50 -0
  4. package/dist/errors.d.ts.map +1 -0
  5. package/dist/errors.js +87 -0
  6. package/dist/errors.js.map +1 -0
  7. package/dist/index.d.ts +21 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +25 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/indexes/search-index.d.ts +368 -0
  12. package/dist/indexes/search-index.d.ts.map +1 -0
  13. package/dist/indexes/search-index.js +475 -0
  14. package/dist/indexes/search-index.js.map +1 -0
  15. package/dist/query/base.d.ts +51 -0
  16. package/dist/query/base.d.ts.map +1 -0
  17. package/dist/query/base.js +6 -0
  18. package/dist/query/base.js.map +1 -0
  19. package/dist/query/index.d.ts +7 -0
  20. package/dist/query/index.d.ts.map +1 -0
  21. package/dist/query/index.js +7 -0
  22. package/dist/query/index.js.map +1 -0
  23. package/dist/query/vector.d.ts +199 -0
  24. package/dist/query/vector.d.ts.map +1 -0
  25. package/dist/query/vector.js +198 -0
  26. package/dist/query/vector.js.map +1 -0
  27. package/dist/redis/index-info-parser.d.ts +25 -0
  28. package/dist/redis/index-info-parser.d.ts.map +1 -0
  29. package/dist/redis/index-info-parser.js +301 -0
  30. package/dist/redis/index-info-parser.js.map +1 -0
  31. package/dist/redis/schema-types.d.ts +81 -0
  32. package/dist/redis/schema-types.d.ts.map +1 -0
  33. package/dist/redis/schema-types.js +18 -0
  34. package/dist/redis/schema-types.js.map +1 -0
  35. package/dist/redis/utils.d.ts +7 -0
  36. package/dist/redis/utils.d.ts.map +1 -0
  37. package/dist/redis/utils.js +221 -0
  38. package/dist/redis/utils.js.map +1 -0
  39. package/dist/schema/fields.d.ts +163 -0
  40. package/dist/schema/fields.d.ts.map +1 -0
  41. package/dist/schema/fields.js +304 -0
  42. package/dist/schema/fields.js.map +1 -0
  43. package/dist/schema/index.d.ts +8 -0
  44. package/dist/schema/index.d.ts.map +1 -0
  45. package/dist/schema/index.js +8 -0
  46. package/dist/schema/index.js.map +1 -0
  47. package/dist/schema/schema.d.ts +247 -0
  48. package/dist/schema/schema.d.ts.map +1 -0
  49. package/dist/schema/schema.js +403 -0
  50. package/dist/schema/schema.js.map +1 -0
  51. package/dist/schema/types.d.ts +56 -0
  52. package/dist/schema/types.d.ts.map +1 -0
  53. package/dist/schema/types.js +62 -0
  54. package/dist/schema/types.js.map +1 -0
  55. package/dist/storage/base-storage.d.ts +107 -0
  56. package/dist/storage/base-storage.d.ts.map +1 -0
  57. package/dist/storage/base-storage.js +187 -0
  58. package/dist/storage/base-storage.js.map +1 -0
  59. package/dist/storage/hash-storage.d.ts +29 -0
  60. package/dist/storage/hash-storage.d.ts.map +1 -0
  61. package/dist/storage/hash-storage.js +122 -0
  62. package/dist/storage/hash-storage.js.map +1 -0
  63. package/dist/storage/index.d.ts +4 -0
  64. package/dist/storage/index.d.ts.map +1 -0
  65. package/dist/storage/index.js +4 -0
  66. package/dist/storage/index.js.map +1 -0
  67. package/dist/storage/json-storage.d.ts +19 -0
  68. package/dist/storage/json-storage.d.ts.map +1 -0
  69. package/dist/storage/json-storage.js +81 -0
  70. package/dist/storage/json-storage.js.map +1 -0
  71. package/dist/utils/distance.d.ts +92 -0
  72. package/dist/utils/distance.d.ts.map +1 -0
  73. package/dist/utils/distance.js +98 -0
  74. package/dist/utils/distance.js.map +1 -0
  75. package/dist/vectorizers/base-vectorizer.d.ts +88 -0
  76. package/dist/vectorizers/base-vectorizer.d.ts.map +1 -0
  77. package/dist/vectorizers/base-vectorizer.js +32 -0
  78. package/dist/vectorizers/base-vectorizer.js.map +1 -0
  79. package/dist/vectorizers/huggingface-vectorizer.d.ts +103 -0
  80. package/dist/vectorizers/huggingface-vectorizer.d.ts.map +1 -0
  81. package/dist/vectorizers/huggingface-vectorizer.js +142 -0
  82. package/dist/vectorizers/huggingface-vectorizer.js.map +1 -0
  83. package/dist/vectorizers/index.d.ts +10 -0
  84. package/dist/vectorizers/index.d.ts.map +1 -0
  85. package/dist/vectorizers/index.js +10 -0
  86. package/dist/vectorizers/index.js.map +1 -0
  87. package/package.json +96 -0
@@ -0,0 +1,368 @@
1
+ /**
2
+ * @module Search Index
3
+ * Main search index class for managing Redis search indexes.
4
+ */
5
+ import type { RedisClientType, RedisClusterType } from 'redis';
6
+ import { IndexSchema } from '../schema/schema.js';
7
+ import type { BaseQuery, SearchResult, QueryOptions } from '../query/base.js';
8
+ /**
9
+ * Options for creating an index.
10
+ */
11
+ export interface CreateIndexOptions {
12
+ /**
13
+ * Whether to overwrite the index if it already exists.
14
+ * @default false
15
+ */
16
+ overwrite?: boolean;
17
+ /**
18
+ * Whether to drop all keys associated with the index when overwriting.
19
+ * Only applies when overwrite is true.
20
+ * @default false
21
+ */
22
+ drop?: boolean;
23
+ }
24
+ /**
25
+ * Options for deleting an index.
26
+ */
27
+ export interface DeleteIndexOptions {
28
+ /**
29
+ * Whether to drop all keys associated with the index.
30
+ * @default false
31
+ */
32
+ drop?: boolean;
33
+ }
34
+ /**
35
+ * Options for loading data into an index.
36
+ */
37
+ export interface LoadOptions {
38
+ /**
39
+ * Field name to use as the document ID.
40
+ * If provided, the value of this field will be used as the key.
41
+ * If not provided, keys will be auto-generated.
42
+ */
43
+ idField?: string;
44
+ /**
45
+ * Explicit keys to use for the documents.
46
+ * Must match the length of the data array.
47
+ */
48
+ keys?: string[];
49
+ /**
50
+ * Time-to-live in seconds for the documents.
51
+ * If provided, documents will expire after this duration.
52
+ */
53
+ ttl?: number;
54
+ /**
55
+ * Number of objects to write in a single Redis pipeline execution.
56
+ * @default 200
57
+ */
58
+ batchSize?: number;
59
+ /**
60
+ * Preprocessing function to transform documents before loading.
61
+ * The function receives a document and returns a Promise of the transformed document.
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * // Simple transformation
66
+ * await index.load(data, {
67
+ * preprocess: async (doc) => ({ ...doc, timestamp: Date.now() })
68
+ * });
69
+ *
70
+ * // generating embeddings
71
+ * await index.load(data, {
72
+ * preprocess: async (doc) => ({
73
+ * ...doc,
74
+ * embedding: await vectorizer.embed(doc.text)
75
+ * })
76
+ * });
77
+ * ```
78
+ */
79
+ preprocess?: (doc: Record<string, unknown>) => Promise<Record<string, unknown>>;
80
+ /**
81
+ * Whether to validate documents against schema before loading.
82
+ * @default false
83
+ */
84
+ validateOnLoad?: boolean;
85
+ }
86
+ /**
87
+ * SearchIndex class for managing Redis vector search indices.
88
+ *
89
+ * This class provides methods to create, manage, and query Redis search indices.
90
+ * Users create their own Redis client and pass it to the constructor.
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * import { createClient } from 'redis';
95
+ * import { SearchIndex, IndexSchema, StorageType } from 'redis-vl';
96
+ *
97
+ * const client = createClient();
98
+ * await client.connect();
99
+ *
100
+ * const schema = new IndexSchema({
101
+ * index: { name: 'my-index', prefix: 'doc', storageType: StorageType.HASH }
102
+ * });
103
+ * schema.addField({ name: 'title', type: 'text' });
104
+ *
105
+ * const searchIndex = new SearchIndex(schema, client);
106
+ * await searchIndex.create();
107
+ * ```
108
+ */
109
+ export declare class SearchIndex {
110
+ /**
111
+ * The index schema defining the structure and fields.
112
+ */
113
+ readonly schema: IndexSchema;
114
+ /**
115
+ * The Redis client instance.
116
+ */
117
+ private readonly client;
118
+ /**
119
+ * Internal storage handler for data operations.
120
+ */
121
+ private readonly storage;
122
+ /**
123
+ * Whether to validate documents against schema when loading.
124
+ * Can be overridden per load() call.
125
+ */
126
+ private readonly validateOnLoad;
127
+ /**
128
+ * Create a new SearchIndex instance.
129
+ *
130
+ * @param schema - The index schema
131
+ * @param client - Redis client instance (created by user)
132
+ * @param validateOnLoad - Whether to validate documents on load (default: false)
133
+ * @throws {Error} If schema is not a valid IndexSchema instance
134
+ * @throws {Error} If client is not provided
135
+ */
136
+ constructor(schema: IndexSchema, client: RedisClientType | RedisClusterType, validateOnLoad?: boolean);
137
+ /**
138
+ * Load an existing index from Redis by name.
139
+ *
140
+ * This method fetches the index metadata using FT.INFO and reconstructs
141
+ * the IndexSchema from the stored information.
142
+ *
143
+ * @param name - Name of the existing index in Redis
144
+ * @param client - Redis client instance
145
+ * @param validateOnLoad - Whether to validate documents on load (default: false)
146
+ * @returns SearchIndex instance with reconstructed schema
147
+ * @throws {RedisVLError} If index doesn't exist or cannot be loaded
148
+ *
149
+ * @example
150
+ * ```typescript
151
+ * // Load an existing index
152
+ * const index = await SearchIndex.fromExisting('my-index', client);
153
+ *
154
+ * // Use the loaded index
155
+ * const docs = await index.fetchMany(['key1', 'key2']);
156
+ * ```
157
+ */
158
+ static fromExisting(name: string, client: RedisClientType | RedisClusterType, validateOnLoad?: boolean): Promise<SearchIndex>;
159
+ /**
160
+ * Get the index name from the schema.
161
+ */
162
+ get name(): string;
163
+ /**
164
+ * Convert schema fields to Redis field schema format.
165
+ * Each field class knows how to convert itself via the toRedisField() method.
166
+ * @private
167
+ */
168
+ private convertFieldsToRedisSchema;
169
+ private getVectorScoreAlias;
170
+ private getVectorDistanceNormalizer;
171
+ /**
172
+ * Create the index in Redis.
173
+ *
174
+ * @param options - Creation options
175
+ * @throws {Error} If no fields are defined for the index
176
+ * @returns The result from Redis FT.CREATE command
177
+ */
178
+ create(options?: CreateIndexOptions): Promise<"OK" | undefined>;
179
+ /**
180
+ * Check if the index exists in Redis.
181
+ *
182
+ * @returns True if the index exists, false otherwise
183
+ */
184
+ exists(): Promise<boolean>;
185
+ /**
186
+ * Delete the index from Redis.
187
+ *
188
+ * @param options - Deletion options
189
+ * @returns The result from Redis FT.DROPINDEX command
190
+ */
191
+ delete(options?: DeleteIndexOptions): Promise<"OK">;
192
+ /**
193
+ * Get information about the index.
194
+ *
195
+ * @returns Index information from Redis
196
+ */
197
+ info(): Promise<{
198
+ index_name: string;
199
+ index_options: string[];
200
+ index_definition: {
201
+ [x: string]: string;
202
+ };
203
+ attributes: {
204
+ [x: string]: string;
205
+ }[];
206
+ num_docs: number;
207
+ max_doc_id: number;
208
+ num_terms: number;
209
+ num_records: number;
210
+ inverted_sz_mb: number;
211
+ vector_index_sz_mb: number;
212
+ total_inverted_index_blocks: number;
213
+ offset_vectors_sz_mb: number;
214
+ doc_table_size_mb: number;
215
+ sortable_values_size_mb: number;
216
+ key_table_size_mb: number;
217
+ tag_overhead_sz_mb: number;
218
+ text_overhead_sz_mb: number;
219
+ total_index_memory_sz_mb: number;
220
+ geoshapes_sz_mb: number;
221
+ records_per_doc_avg: number;
222
+ bytes_per_record_avg: number;
223
+ offsets_per_term_avg: number;
224
+ offset_bits_per_record_avg: number;
225
+ hash_indexing_failures: number;
226
+ total_indexing_time: number;
227
+ indexing: number;
228
+ percent_indexed: number;
229
+ number_of_uses: number;
230
+ cleaning: number;
231
+ gc_stats: {
232
+ bytes_collected: number;
233
+ total_ms_run: number;
234
+ total_cycles: number;
235
+ average_cycle_time_ms: number;
236
+ last_run_time_ms: number;
237
+ gc_numeric_trees_missed: number;
238
+ gc_blocks_denied: number;
239
+ };
240
+ cursor_stats: {
241
+ global_idle: number;
242
+ global_total: number;
243
+ index_capacity: number;
244
+ index_total: number;
245
+ };
246
+ stopwords_list?: string[] | null[] | undefined;
247
+ }>;
248
+ /**
249
+ * Load documents into the index.
250
+ *
251
+ * This method handles:
252
+ * - Auto-generating keys using ULID if no idField or keys provided
253
+ * - Extracting IDs from documents using idField
254
+ * - Using explicit keys if provided
255
+ * - Preprocessing documents before storage
256
+ * - Setting TTL on documents
257
+ * - Supporting both HASH and JSON storage types
258
+ * - Batching operations using Redis pipelining for performance
259
+ * - Optional schema validation
260
+ *
261
+ * @param data - Array of documents to load
262
+ * @param options - Load options
263
+ * @returns Array of keys that were loaded
264
+ * @throws {Error} If keys length doesn't match data length
265
+ * @throws {Error} If idField is not found in a document
266
+ * @throws {SchemaValidationError} If validation fails when validateOnLoad is enabled
267
+ * @throws {RedisVLError} If there's an error loading data to Redis
268
+ *
269
+ * @example
270
+ * ```typescript
271
+ * // Auto-generate keys
272
+ * const keys = await index.load([
273
+ * { title: 'Doc 1', score: 100 },
274
+ * { title: 'Doc 2', score: 200 }
275
+ * ]);
276
+ *
277
+ * // Use idField
278
+ * const keys = await index.load(
279
+ * [{ id: 'user1', name: 'John' }],
280
+ * { idField: 'id' }
281
+ * );
282
+ *
283
+ * // Use explicit keys
284
+ * const keys = await index.load(
285
+ * [{ name: 'John' }],
286
+ * { keys: ['user:1'] }
287
+ * );
288
+ *
289
+ * // With preprocessing, TTL, and validation
290
+ * const keys = await index.load(
291
+ * [{ name: 'John' }],
292
+ * {
293
+ * ttl: 3600,
294
+ * batchSize: 100,
295
+ * validateOnLoad: true,
296
+ * preprocess: (doc) => ({ ...doc, timestamp: Date.now() })
297
+ * }
298
+ * );
299
+ * ```
300
+ */
301
+ load(data: Record<string, unknown>[], options?: LoadOptions): Promise<string[]>;
302
+ /**
303
+ * Fetch a single document by key.
304
+ *
305
+ * @param key - The document key (without prefix)
306
+ * @returns The document or null if not found
307
+ *
308
+ * @example
309
+ * ```typescript
310
+ * const doc = await index.fetch('123');
311
+ */
312
+ fetch(key: string): Promise<Record<string, unknown> | null>;
313
+ /**
314
+ * Fetch multiple documents by keys.
315
+ * Uses pipelining for efficient batch retrieval.
316
+ *
317
+ * @param keys - Array of document keys (without prefix)
318
+ * @param batchSize - Number of commands per pipeline batch (default: 200)
319
+ * @returns Array of documents (null for missing keys)
320
+ *
321
+ * @example
322
+ * ```typescript
323
+ * const docs = await index.fetchMany(['123', '456', '789']);
324
+ */
325
+ fetchMany(keys: string[], batchSize?: number): Promise<(Record<string, unknown> | null)[]>;
326
+ /**
327
+ * Execute a search query against the index
328
+ *
329
+ * @param query - Query object (VectorQuery, FilterQuery, etc.)
330
+ * @param options - Optional query execution options
331
+ * @returns Search results with documents and scores
332
+ *
333
+ * @example
334
+ * ```typescript
335
+ * import { VectorQuery } from 'redis-vl';
336
+ *
337
+ * // Vector similarity search
338
+ * const query = new VectorQuery({
339
+ * vector: embedding,
340
+ * vectorField: 'embedding',
341
+ * topK: 10,
342
+ * returnFields: ['title', 'content']
343
+ * });
344
+ *
345
+ * const results = await index.search(query);
346
+ * console.log(`Found ${results.total} results`);
347
+ *
348
+ * results.documents.forEach((doc) => {
349
+ * console.log(`${doc.value.title} (score: ${doc.score})`);
350
+ * });
351
+ * ```
352
+ *
353
+ * @example
354
+ * ```typescript
355
+ * // Vector search with metadata filtering
356
+ * const query = new VectorQuery({
357
+ * vector: embedding,
358
+ * vectorField: 'embedding',
359
+ * filter: '@category:{electronics}',
360
+ * topK: 5
361
+ * });
362
+ *
363
+ * const results = await index.search(query);
364
+ * ```
365
+ */
366
+ search<T = Record<string, unknown>>(query: BaseQuery, options?: QueryOptions): Promise<SearchResult<T>>;
367
+ }
368
+ //# sourceMappingURL=search-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-index.d.ts","sourceRoot":"","sources":["../../src/indexes/search-index.ts"],"names":[],"mappings":"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"}