diff --git a/packages/search/lib/commands/CREATE.spec.ts b/packages/search/lib/commands/CREATE.spec.ts index dad983c0038..5a622f1fd8a 100644 --- a/packages/search/lib/commands/CREATE.spec.ts +++ b/packages/search/lib/commands/CREATE.spec.ts @@ -69,24 +69,43 @@ describe('FT.CREATE', () => { ['FT.CREATE', 'index', 'SCHEMA', 'field', 'TEXT', 'WITHSUFFIXTRIE'] ); }); + it('with INDEXEMPTY', () => { + assert.deepEqual( + CREATE.transformArguments('index', { + field: { + type: SCHEMA_FIELD_TYPE.TEXT, + INDEXEMPTY: true + } + }), + ['FT.CREATE', 'index', 'SCHEMA', 'field', 'TEXT', 'INDEXEMPTY'] + ); + }); }); - it('NUMERIC', () => { - assert.deepEqual( - CREATE.transformArguments('index', { - field: SCHEMA_FIELD_TYPE.NUMERIC - }), - ['FT.CREATE', 'index', 'SCHEMA', 'field', 'NUMERIC'] - ); + describe('NUMERIC', () => { + describe('transformArguments', () => { + it('no options', () => { + assert.deepEqual( + CREATE.transformArguments('index', { + field: SCHEMA_FIELD_TYPE.NUMERIC + }), + ['FT.CREATE', 'index', 'SCHEMA', 'field', 'NUMERIC'] + ); + }); + }); }); - it('GEO', () => { - assert.deepEqual( - CREATE.transformArguments('index', { - field: SCHEMA_FIELD_TYPE.GEO - }), - ['FT.CREATE', 'index', 'SCHEMA', 'field', 'GEO'] - ); + describe('GEO', () => { + describe('transformArguments', () => { + it('no options', () => { + assert.deepEqual( + CREATE.transformArguments('index', { + field: SCHEMA_FIELD_TYPE.GEO + }), + ['FT.CREATE', 'index', 'SCHEMA', 'field', 'GEO'] + ); + }); + }); }); describe('TAG', () => { @@ -147,6 +166,18 @@ describe('FT.CREATE', () => { ['FT.CREATE', 'index', 'SCHEMA', 'field', 'TAG', 'WITHSUFFIXTRIE'] ); }); + + it('with INDEXEMPTY', () => { + assert.deepEqual( + CREATE.transformArguments('index', { + field: { + type: SCHEMA_FIELD_TYPE.TAG, + INDEXEMPTY: true + } + }), + ['FT.CREATE', 'index', 'SCHEMA', 'field', 'TAG', 'INDEXEMPTY'] + ); + }); }); describe('VECTOR', () => { @@ -282,6 +313,18 @@ describe('FT.CREATE', () => { }); }); + it('with INDEXMISSING', () => { + assert.deepEqual( + CREATE.transformArguments('index', { + field: { + type: SCHEMA_FIELD_TYPE.TEXT, + INDEXMISSING: true + } + }), + ['FT.CREATE', 'index', 'SCHEMA', 'field', 'TEXT', 'INDEXMISSING'] + ); + }); + it('with ON', () => { assert.deepEqual( CREATE.transformArguments('index', {}, { diff --git a/packages/search/lib/commands/CREATE.ts b/packages/search/lib/commands/CREATE.ts index f6b66085f2d..1094adc7e50 100644 --- a/packages/search/lib/commands/CREATE.ts +++ b/packages/search/lib/commands/CREATE.ts @@ -18,19 +18,36 @@ type SchemaField< > = T | ({ type: T; AS?: RedisArgument; + INDEXMISSING?: boolean; } & E); +type CommonFieldArguments = { + SORTABLE?: boolean | 'UNF'; + NOINDEX?: boolean; +}; + type SchemaCommonField< T extends SchemaFieldType, E = Record > = SchemaField< - T, - ({ - SORTABLE?: boolean | 'UNF'; - NOINDEX?: boolean; - } & E) + T, + (CommonFieldArguments & E) >; +function pushCommonFieldArguments(args: CommandArguments, fieldOptions: CommonFieldArguments) { + if (fieldOptions.SORTABLE) { + args.push('SORTABLE'); + + if (fieldOptions.SORTABLE === 'UNF') { + args.push('UNF'); + } + } + + if (fieldOptions.NOINDEX) { + args.push('NOINDEX'); + } +} + export const SCHEMA_TEXT_FIELD_PHONETIC = { DM_EN: 'dm:en', DM_FR: 'dm:fr', @@ -45,6 +62,7 @@ type SchemaTextField = SchemaCommonField; type SchemaNumericField = SchemaCommonField; @@ -55,6 +73,7 @@ type SchemaTagField = SchemaCommonField; export const SCHEMA_VECTOR_FIELD_ALGORITHM = { @@ -92,7 +111,7 @@ export const SCHEMA_GEO_SHAPE_COORD_SYSTEM = { export type SchemaGeoShapeFieldCoordSystem = typeof SCHEMA_GEO_SHAPE_COORD_SYSTEM[keyof typeof SCHEMA_GEO_SHAPE_COORD_SYSTEM]; -type SchemaGeoShapeField = SchemaField; @@ -141,11 +160,18 @@ export function pushSchema(args: CommandArguments, schema: RediSearchSchema) { args.push('WITHSUFFIXTRIE'); } + pushCommonFieldArguments(args, fieldOptions); + + if (fieldOptions.INDEXEMPTY) { + args.push('INDEXEMPTY'); + } + break; - // case SchemaFieldTypes.NUMERIC: - // case SchemaFieldTypes.GEO: - // break; + case SCHEMA_FIELD_TYPE.NUMERIC: + case SCHEMA_FIELD_TYPE.GEO: + pushCommonFieldArguments(args, fieldOptions); + break; case SCHEMA_FIELD_TYPE.TAG: if (fieldOptions.SEPARATOR) { @@ -160,6 +186,12 @@ export function pushSchema(args: CommandArguments, schema: RediSearchSchema) { args.push('WITHSUFFIXTRIE'); } + pushCommonFieldArguments(args, fieldOptions); + + if (fieldOptions.INDEXEMPTY) { + args.push('INDEXEMPTY'); + } + break; case SCHEMA_FIELD_TYPE.VECTOR: @@ -200,28 +232,23 @@ export function pushSchema(args: CommandArguments, schema: RediSearchSchema) { break; } + args[lengthIndex] = (args.length - lengthIndex - 1).toString(); - continue; // vector fields do not contain SORTABLE and NOINDEX options + break; case SCHEMA_FIELD_TYPE.GEOSHAPE: if (fieldOptions.COORD_SYSTEM !== undefined) { args.push('COORD_SYSTEM', fieldOptions.COORD_SYSTEM); } - continue; // geo shape fields do not contain SORTABLE and NOINDEX options - } - - if (fieldOptions.SORTABLE) { - args.push('SORTABLE'); + pushCommonFieldArguments(args, fieldOptions); - if (fieldOptions.SORTABLE === 'UNF') { - args.push('UNF'); - } + break; // geo shape fields do not contain SORTABLE and NOINDEX options } - if (fieldOptions.NOINDEX) { - args.push('NOINDEX'); + if (fieldOptions.INDEXMISSING) { + args.push('INDEXMISSING'); } } }