From 42e274124f677193dac9fb04be70bd68c5b73b58 Mon Sep 17 00:00:00 2001 From: Nikolay Karadzhov Date: Wed, 22 Jul 2026 14:34:03 +0300 Subject: [PATCH] feat(search): add RERANK parameter for HNSW vector fields Add the optional RERANK boolean to HNSW vector field definitions in FT.CREATE, introduced in Redis 8.10 for disk-based vector indexes. When set, the client emits `RERANK TRUE` / `RERANK FALSE`; it is only sent when explicitly provided. The parameter is HNSW-only and confined to the HNSW schema type. Co-Authored-By: Claude Opus 4.8 (1M context) --- packages/search/lib/commands/CREATE.spec.ts | 57 +++++++++++++++++++++ packages/search/lib/commands/CREATE.ts | 9 ++++ 2 files changed, 66 insertions(+) diff --git a/packages/search/lib/commands/CREATE.spec.ts b/packages/search/lib/commands/CREATE.spec.ts index 833044f0baa..803fdb33339 100644 --- a/packages/search/lib/commands/CREATE.spec.ts +++ b/packages/search/lib/commands/CREATE.spec.ts @@ -207,6 +207,44 @@ describe('FT.CREATE', () => { ); }); + it('HNSW algorithm with RERANK', () => { + assert.deepEqual( + parseArgs(CREATE, 'index', { + field: { + type: SCHEMA_FIELD_TYPE.VECTOR, + ALGORITHM: SCHEMA_VECTOR_FIELD_ALGORITHM.HNSW, + TYPE: 'FLOAT32', + DIM: 2, + DISTANCE_METRIC: 'L2', + RERANK: true + } + }), + [ + 'FT.CREATE', 'index', 'SCHEMA', 'field', 'VECTOR', 'HNSW', '8', 'TYPE', + 'FLOAT32', 'DIM', '2', 'DISTANCE_METRIC', 'L2', 'RERANK', 'TRUE' + ] + ); + }); + + it('HNSW algorithm with RERANK false', () => { + assert.deepEqual( + parseArgs(CREATE, 'index', { + field: { + type: SCHEMA_FIELD_TYPE.VECTOR, + ALGORITHM: SCHEMA_VECTOR_FIELD_ALGORITHM.HNSW, + TYPE: 'FLOAT32', + DIM: 2, + DISTANCE_METRIC: 'L2', + RERANK: false + } + }), + [ + 'FT.CREATE', 'index', 'SCHEMA', 'field', 'VECTOR', 'HNSW', '8', 'TYPE', + 'FLOAT32', 'DIM', '2', 'DISTANCE_METRIC', 'L2', 'RERANK', 'FALSE' + ] + ); + }); + it('VAMANA algorithm', () => { assert.deepEqual( parseArgs(CREATE, 'index', { @@ -642,6 +680,25 @@ describe('FT.CREATE', () => { ); }, GLOBAL.SERVERS.OPEN); + testUtils.testWithClientIfVersionWithinRange([[8, 10], 'LATEST'], 'client.ft.create vector hnsw rerank', async client => { + // RERANK is only valid for disk-based vector indexes, which the OSS test + // server cannot create. Assert the parameter reaches the server and is + // recognized (rejected only for the index type, not as a syntax error). + await assert.rejects( + client.ft.create('index_hnsw_rerank', { + field: { + type: SCHEMA_FIELD_TYPE.VECTOR, + ALGORITHM: SCHEMA_VECTOR_FIELD_ALGORITHM.HNSW, + TYPE: 'FLOAT32', + DIM: 5, + DISTANCE_METRIC: 'L2', + RERANK: true + }, + }), + /disk-based/ + ); + }, GLOBAL.SERVERS.OPEN); + testUtils.testWithClientIfVersionWithinRange([[8, 2], 'LATEST'], 'client.ft.create vector svs-vamana', async client => { assert.equal( await client.ft.create("index_svs_vamana_min_config", { diff --git a/packages/search/lib/commands/CREATE.ts b/packages/search/lib/commands/CREATE.ts index 00dee3ef975..34aeb49393f 100644 --- a/packages/search/lib/commands/CREATE.ts +++ b/packages/search/lib/commands/CREATE.ts @@ -81,6 +81,11 @@ interface SchemaHNSWVectorField extends SchemaVectorField { M?: number; EF_CONSTRUCTION?: number; EF_RUNTIME?: number; + /** + * Enable reranking. Requires a disk-based vector index. + * available since 8.10 + */ + RERANK?: boolean; } export const VAMANA_COMPRESSION_ALGORITHM = { @@ -293,6 +298,10 @@ export function parseSchema(parser: CommandParser, schema: RediSearchSchema) { args.push('EF_RUNTIME', fieldOptions.EF_RUNTIME.toString()); } + if (fieldOptions.RERANK !== undefined) { + args.push('RERANK', fieldOptions.RERANK ? 'TRUE' : 'FALSE'); + } + break; case SCHEMA_VECTOR_FIELD_ALGORITHM['VAMANA']: