1
1
import * as _LIST from './_LIST' ;
2
+ import * as ALTER from './ALTER' ;
2
3
import * as AGGREGATE from './AGGREGATE' ;
3
4
import * as ALIASADD from './ALIASADD' ;
4
5
import * as ALIASDEL from './ALIASDEL' ;
@@ -13,7 +14,8 @@ import * as DROPINDEX from './DROPINDEX';
13
14
import * as EXPLAIN from './EXPLAIN' ;
14
15
import * as EXPLAINCLI from './EXPLAINCLI' ;
15
16
import * as INFO from './INFO' ;
16
- // import * as PROFILE from './PROFILE';
17
+ import * as PROFILESEARCH from './PROFILE_SEARCH' ;
18
+ import * as PROFILEAGGREGATE from './PROFILE_AGGREGATE' ;
17
19
import * as SEARCH from './SEARCH' ;
18
20
import * as SPELLCHECK from './SPELLCHECK' ;
19
21
import * as SUGADD from './SUGADD' ;
@@ -27,10 +29,15 @@ import * as SYNDUMP from './SYNDUMP';
27
29
import * as SYNUPDATE from './SYNUPDATE' ;
28
30
import * as TAGVALS from './TAGVALS' ;
29
31
import { RedisCommandArguments } from '@node-redis/client/dist/lib/commands' ;
32
+ import { pushOptionalVerdictArgument , pushVerdictArgument , TuplesObject } from '@node-redis/client/dist/lib/commands/generic-transformers' ;
33
+ import internal = require( 'stream' ) ;
34
+ import { SearchOptions } from './SEARCH' ;
30
35
31
36
export default {
32
37
_LIST ,
33
38
_list : _LIST ,
39
+ ALTER ,
40
+ alter : ALTER ,
34
41
AGGREGATE ,
35
42
aggregate : AGGREGATE ,
36
43
ALIASADD ,
@@ -59,8 +66,10 @@ export default {
59
66
explainCli : EXPLAINCLI ,
60
67
INFO ,
61
68
info : INFO ,
62
- // PROFILE,
63
- // profile: PROFILE,
69
+ PROFILESEARCH ,
70
+ profileSearch : PROFILESEARCH ,
71
+ PROFILEAGGREGATE ,
72
+ profileAggregate : PROFILEAGGREGATE ,
64
73
SEARCH ,
65
74
search : SEARCH ,
66
75
SPELLCHECK ,
@@ -159,3 +168,347 @@ export function pushArgumentsWithLength(args: RedisCommandArguments, fn: (args:
159
168
args [ lengthIndex ] = ( args . length - lengthIndex - 1 ) . toString ( ) ;
160
169
return args ;
161
170
}
171
+
172
+ export enum SchemaFieldTypes {
173
+ TEXT = 'TEXT' ,
174
+ NUMERIC = 'NUMERIC' ,
175
+ GEO = 'GEO' ,
176
+ TAG = 'TAG'
177
+ }
178
+
179
+ type CreateSchemaField < T extends SchemaFieldTypes , E = Record < string , never > > = T | ( {
180
+ type : T ;
181
+ AS ?: string ;
182
+ SORTABLE ?: true | 'UNF' ;
183
+ NOINDEX ?: true ;
184
+ } & E ) ;
185
+
186
+ export enum SchemaTextFieldPhonetics {
187
+ DM_EN = 'dm:en' ,
188
+ DM_FR = 'dm:fr' ,
189
+ FM_PT = 'dm:pt' ,
190
+ DM_ES = 'dm:es'
191
+ }
192
+
193
+ type CreateSchemaTextField = CreateSchemaField < SchemaFieldTypes . TEXT , {
194
+ NOSTEM ?: true ;
195
+ WEIGHT ?: number ;
196
+ PHONETIC ?: SchemaTextFieldPhonetics ;
197
+ } > ;
198
+
199
+ type CreateSchemaNumericField = CreateSchemaField < SchemaFieldTypes . NUMERIC > ;
200
+
201
+ type CreateSchemaGeoField = CreateSchemaField < SchemaFieldTypes . GEO > ;
202
+
203
+ type CreateSchemaTagField = CreateSchemaField < SchemaFieldTypes . TAG , {
204
+ SEPERATOR ?: string ;
205
+ CASESENSITIVE ?: true ;
206
+ } > ;
207
+
208
+ export interface CreateSchema {
209
+ [ field : string ] :
210
+ CreateSchemaTextField |
211
+ CreateSchemaNumericField |
212
+ CreateSchemaGeoField |
213
+ CreateSchemaTagField
214
+ }
215
+
216
+ export function pushSchema ( args : RedisCommandArguments , schema : CreateSchema ) {
217
+ for ( const [ field , fieldOptions ] of Object . entries ( schema ) ) {
218
+ args . push ( field ) ;
219
+
220
+ if ( typeof fieldOptions === 'string' ) {
221
+ args . push ( fieldOptions ) ;
222
+ continue ;
223
+ }
224
+
225
+ if ( fieldOptions . AS ) {
226
+ args . push ( 'AS' , fieldOptions . AS ) ;
227
+ }
228
+
229
+ args . push ( fieldOptions . type ) ;
230
+
231
+ switch ( fieldOptions . type ) {
232
+ case 'TEXT' :
233
+ if ( fieldOptions . NOSTEM ) {
234
+ args . push ( 'NOSTEM' ) ;
235
+ }
236
+
237
+ if ( fieldOptions . WEIGHT ) {
238
+ args . push ( 'WEIGHT' , fieldOptions . WEIGHT . toString ( ) ) ;
239
+ }
240
+
241
+ if ( fieldOptions . PHONETIC ) {
242
+ args . push ( 'PHONETIC' , fieldOptions . PHONETIC ) ;
243
+ }
244
+
245
+ break ;
246
+
247
+ // case 'NUMERIC':
248
+ // case 'GEO':
249
+ // break;
250
+
251
+ case 'TAG' :
252
+ if ( fieldOptions . SEPERATOR ) {
253
+ args . push ( 'SEPERATOR' , fieldOptions . SEPERATOR ) ;
254
+ }
255
+
256
+ if ( fieldOptions . CASESENSITIVE ) {
257
+ args . push ( 'CASESENSITIVE' ) ;
258
+ }
259
+
260
+ break ;
261
+ }
262
+
263
+ if ( fieldOptions . SORTABLE ) {
264
+ args . push ( 'SORTABLE' ) ;
265
+
266
+ if ( fieldOptions . SORTABLE === 'UNF' ) {
267
+ args . push ( 'UNF' ) ;
268
+ }
269
+ }
270
+
271
+ if ( fieldOptions . NOINDEX ) {
272
+ args . push ( 'NOINDEX' ) ;
273
+ }
274
+ }
275
+ }
276
+
277
+ export function pushSearchOptions (
278
+ args : RedisCommandArguments ,
279
+ options ?: SearchOptions
280
+ ) : RedisCommandArguments {
281
+
282
+ if ( options ?. VERBATIM ) {
283
+ args . push ( 'VERBATIM' ) ;
284
+ }
285
+
286
+ if ( options ?. NOSTOPWORDS ) {
287
+ args . push ( 'NOSTOPWORDS' ) ;
288
+ }
289
+
290
+ // if (options?.WITHSCORES) {
291
+ // args.push('WITHSCORES');
292
+ // }
293
+
294
+ // if (options?.WITHPAYLOADS) {
295
+ // args.push('WITHPAYLOADS');
296
+ // }
297
+
298
+ pushOptionalVerdictArgument ( args , 'INKEYS' , options ?. INKEYS ) ;
299
+ pushOptionalVerdictArgument ( args , 'INFIELDS' , options ?. INFIELDS ) ;
300
+ pushOptionalVerdictArgument ( args , 'RETURN' , options ?. RETURN ) ;
301
+
302
+ if ( options ?. SUMMARIZE ) {
303
+ args . push ( 'SUMMARIZE' ) ;
304
+
305
+ if ( typeof options . SUMMARIZE === 'object' ) {
306
+ if ( options . SUMMARIZE . FIELDS ) {
307
+ args . push ( 'FIELDS' ) ;
308
+ pushVerdictArgument ( args , options . SUMMARIZE . FIELDS ) ;
309
+ }
310
+
311
+ if ( options . SUMMARIZE . FRAGS ) {
312
+ args . push ( 'FRAGS' , options . SUMMARIZE . FRAGS . toString ( ) ) ;
313
+ }
314
+
315
+ if ( options . SUMMARIZE . LEN ) {
316
+ args . push ( 'LEN' , options . SUMMARIZE . LEN . toString ( ) ) ;
317
+ }
318
+
319
+ if ( options . SUMMARIZE . SEPARATOR ) {
320
+ args . push ( 'SEPARATOR' , options . SUMMARIZE . SEPARATOR ) ;
321
+ }
322
+ }
323
+ }
324
+
325
+ if ( options ?. HIGHLIGHT ) {
326
+ args . push ( 'HIGHLIGHT' ) ;
327
+
328
+ if ( typeof options . HIGHLIGHT === 'object' ) {
329
+ if ( options . HIGHLIGHT . FIELDS ) {
330
+ args . push ( 'FIELDS' ) ;
331
+ pushVerdictArgument ( args , options . HIGHLIGHT . FIELDS ) ;
332
+ }
333
+
334
+ if ( options . HIGHLIGHT . TAGS ) {
335
+ args . push ( 'TAGS' , options . HIGHLIGHT . TAGS . open , options . HIGHLIGHT . TAGS . close ) ;
336
+ }
337
+ }
338
+ }
339
+
340
+ if ( options ?. SLOP ) {
341
+ args . push ( 'SLOP' , options . SLOP . toString ( ) ) ;
342
+ }
343
+
344
+ if ( options ?. INORDER ) {
345
+ args . push ( 'INORDER' ) ;
346
+ }
347
+
348
+ if ( options ?. LANGUAGE ) {
349
+ args . push ( 'LANGUAGE' , options . LANGUAGE ) ;
350
+ }
351
+
352
+ if ( options ?. EXPANDER ) {
353
+ args . push ( 'EXPANDER' , options . EXPANDER ) ;
354
+ }
355
+
356
+ if ( options ?. SCORER ) {
357
+ args . push ( 'SCORER' , options . SCORER ) ;
358
+ }
359
+
360
+ // if (options?.EXPLAINSCORE) {
361
+ // args.push('EXPLAINSCORE');
362
+ // }
363
+
364
+ // if (options?.PAYLOAD) {
365
+ // args.push('PAYLOAD', options.PAYLOAD);
366
+ // }
367
+
368
+ if ( options ?. SORTBY ) {
369
+ args . push ( 'SORTBY' ) ;
370
+ pushSortByProperty ( args , options . SORTBY ) ;
371
+ }
372
+
373
+ // if (options?.MSORTBY) {
374
+ // pushSortByArguments(args, 'MSORTBY', options.MSORTBY);
375
+ // }
376
+
377
+ if ( options ?. LIMIT ) {
378
+ args . push (
379
+ 'LIMIT' ,
380
+ options . LIMIT . from . toString ( ) ,
381
+ options . LIMIT . size . toString ( )
382
+ ) ;
383
+ }
384
+
385
+ return args ;
386
+ }
387
+
388
+ interface SearchDocumentValue {
389
+ [ key : string ] : string | number | null | Array < SearchDocumentValue > | SearchDocumentValue ;
390
+ }
391
+
392
+ export interface SearchReply {
393
+ total : number ;
394
+ documents : Array < {
395
+ id : string ;
396
+ value : SearchDocumentValue ;
397
+ } > ;
398
+ }
399
+
400
+ export interface AggregateReply {
401
+ total : number ;
402
+ results : Array < TuplesObject > ;
403
+ }
404
+
405
+ export interface ProfileOptions {
406
+ LIMITED ?: true ;
407
+ }
408
+
409
+ export type ProfileRawReply < T > = [
410
+ results : T ,
411
+ profile : [
412
+ _ : string ,
413
+ TotalProfileTime : string ,
414
+ _ : string ,
415
+ ParsingTime : string ,
416
+ _ : string ,
417
+ PipelineCreationTime : string ,
418
+ _ : string ,
419
+ IteratorsProfile : Array < any >
420
+ ]
421
+ ] ;
422
+
423
+ export interface ProfileReply {
424
+ results : SearchReply | AggregateReply ,
425
+ profile : ProfileData
426
+ }
427
+
428
+ interface ChildIterator {
429
+ type ?: string ,
430
+ counter ?: number ,
431
+ term ?: string ,
432
+ size ?: number ,
433
+ time ?: string ,
434
+ childIterators ?: Array < ChildIterator >
435
+ }
436
+
437
+ interface IteratorsProfile {
438
+ type ?: string ,
439
+ counter ?: number ,
440
+ queryType ?: string ,
441
+ time ?: string ,
442
+ childIterators ?: Array < ChildIterator >
443
+ }
444
+
445
+ interface ProfileData {
446
+ totalProfileTime : string ,
447
+ parsingTime : string ,
448
+ pipelineCreationTime : string ,
449
+ iteratorsProfile : IteratorsProfile
450
+ }
451
+
452
+ export function transformProfile ( reply : Array < any > ) : ProfileData {
453
+ return {
454
+ totalProfileTime : reply [ 0 ] [ 1 ] ,
455
+ parsingTime : reply [ 1 ] [ 1 ] ,
456
+ pipelineCreationTime : reply [ 2 ] [ 1 ] ,
457
+ iteratorsProfile : transformIterators ( reply [ 3 ] [ 1 ] )
458
+ } ;
459
+ }
460
+
461
+ function transformIterators ( IteratorsProfile : Array < any > ) : IteratorsProfile {
462
+ var res : IteratorsProfile = { } ;
463
+ for ( let i = 0 ; i < IteratorsProfile . length ; i += 2 ) {
464
+ const value = IteratorsProfile [ i + 1 ] ;
465
+ switch ( IteratorsProfile [ i ] ) {
466
+ case 'Type' :
467
+ res . type = value ;
468
+ break ;
469
+ case 'Counter' :
470
+ res . counter = value ;
471
+ break ;
472
+ case 'Time' :
473
+ res . time = value ;
474
+ break ;
475
+ case 'Query type' :
476
+ res . queryType = value ;
477
+ break ;
478
+ case 'Child iterators' :
479
+ res . childIterators = value . map ( transformChildIterators ) ;
480
+ break ;
481
+ }
482
+ }
483
+
484
+ return res ;
485
+ }
486
+
487
+ function transformChildIterators ( IteratorsProfile : Array < any > ) : ChildIterator {
488
+ var res : ChildIterator = { } ;
489
+ for ( let i = 1 ; i < IteratorsProfile . length ; i += 2 ) {
490
+ const value = IteratorsProfile [ i + 1 ] ;
491
+ switch ( IteratorsProfile [ i ] ) {
492
+ case 'Type' :
493
+ res . type = value ;
494
+ break ;
495
+ case 'Counter' :
496
+ res . counter = value ;
497
+ break ;
498
+ case 'Time' :
499
+ res . time = value ;
500
+ break ;
501
+ case 'Size' :
502
+ res . size = value ;
503
+ break ;
504
+ case 'Term' :
505
+ res . term = value ;
506
+ break ;
507
+ case 'Child iterators' :
508
+ res . childIterators = value . map ( transformChildIterators ) ;
509
+ break ;
510
+ }
511
+ }
512
+
513
+ return res ;
514
+ }
0 commit comments