From a217cc1a8847b1adeb338006ac2bac84cbd61537 Mon Sep 17 00:00:00 2001 From: Brett Burch Date: Mon, 18 Sep 2023 16:33:17 -0600 Subject: [PATCH] Add support for `FT.SEARCH NOCONTENT` (#2610) * Add support for NOCONTENT in FT.SEARCH * Move support for NOCONTENT search option from client.search to client.searchNoContent * Add test for SEARCH_NOCONTENT#transformReply * Fix typo * Enable test * Update test field type --------- Co-authored-by: Leibale --- packages/search/lib/commands/SEARCH.ts | 1 - .../lib/commands/SEARCH_NOCONTENT.spec.ts | 45 +++++++++++++++++++ .../search/lib/commands/SEARCH_NOCONTENT.ts | 30 +++++++++++++ packages/search/lib/commands/index.ts | 3 ++ 4 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 packages/search/lib/commands/SEARCH_NOCONTENT.spec.ts create mode 100644 packages/search/lib/commands/SEARCH_NOCONTENT.ts diff --git a/packages/search/lib/commands/SEARCH.ts b/packages/search/lib/commands/SEARCH.ts index ef6c0d5c2d..ff7ab7e201 100644 --- a/packages/search/lib/commands/SEARCH.ts +++ b/packages/search/lib/commands/SEARCH.ts @@ -6,7 +6,6 @@ export const FIRST_KEY_INDEX = 1; export const IS_READ_ONLY = true; export interface SearchOptions { - // NOCONTENT?: true; TODO VERBATIM?: true; NOSTOPWORDS?: true; // WITHSCORES?: true; diff --git a/packages/search/lib/commands/SEARCH_NOCONTENT.spec.ts b/packages/search/lib/commands/SEARCH_NOCONTENT.spec.ts new file mode 100644 index 0000000000..da5a6feaba --- /dev/null +++ b/packages/search/lib/commands/SEARCH_NOCONTENT.spec.ts @@ -0,0 +1,45 @@ +import { strict as assert } from 'assert'; +import { SchemaFieldTypes } from '.'; +import testUtils, { GLOBAL } from '../test-utils'; +import { transformArguments, transformReply } from './SEARCH_NOCONTENT'; + +describe('SEARCH_NOCONTENT', () => { + describe('transformArguments', () => { + it('without options', () => { + assert.deepEqual( + transformArguments('index', 'query'), + ['FT.SEARCH', 'index', 'query', 'NOCONTENT'] + ); + }); + }); + + describe('transformReply', () => { + it('returns total and keys', () => { + assert.deepEqual(transformReply([3, '1', '2', '3']), { + total: 3, + documents: ['1', '2', '3'] + }) + }); + }); + + describe('client.ft.searchNoContent', () => { + testUtils.testWithClient('returns total and keys', async client => { + await Promise.all([ + client.ft.create('index', { + field: SchemaFieldTypes.TEXT + }), + client.hSet('1', 'field', 'field1'), + client.hSet('2', 'field', 'field2'), + client.hSet('3', 'field', 'field3') + ]); + + assert.deepEqual( + await client.ft.searchNoContent('index', '*'), + { + total: 3, + documents: ['1','2','3'] + } + ); + }, GLOBAL.SERVERS.OPEN); + }); +}); diff --git a/packages/search/lib/commands/SEARCH_NOCONTENT.ts b/packages/search/lib/commands/SEARCH_NOCONTENT.ts new file mode 100644 index 0000000000..ab50ae2b9f --- /dev/null +++ b/packages/search/lib/commands/SEARCH_NOCONTENT.ts @@ -0,0 +1,30 @@ +import { RedisCommandArguments } from "@redis/client/dist/lib/commands"; +import { pushSearchOptions } from "."; +import { SearchOptions, SearchRawReply } from "./SEARCH"; + +export const FIRST_KEY_INDEX = 1; + +export const IS_READ_ONLY = true; + +export function transformArguments( + index: string, + query: string, + options?: SearchOptions +): RedisCommandArguments { + return pushSearchOptions( + ['FT.SEARCH', index, query, 'NOCONTENT'], + options + ); +} + +export interface SearchNoContentReply { + total: number; + documents: Array; +}; + +export function transformReply(reply: SearchRawReply): SearchNoContentReply { + return { + total: reply[0], + documents: reply.slice(1) + }; +} diff --git a/packages/search/lib/commands/index.ts b/packages/search/lib/commands/index.ts index 0470aff213..75a2b4e380 100644 --- a/packages/search/lib/commands/index.ts +++ b/packages/search/lib/commands/index.ts @@ -20,6 +20,7 @@ import * as INFO from './INFO'; import * as PROFILESEARCH from './PROFILE_SEARCH'; import * as PROFILEAGGREGATE from './PROFILE_AGGREGATE'; import * as SEARCH from './SEARCH'; +import * as SEARCH_NOCONTENT from './SEARCH_NOCONTENT'; import * as SPELLCHECK from './SPELLCHECK'; import * as SUGADD from './SUGADD'; import * as SUGDEL from './SUGDEL'; @@ -80,6 +81,8 @@ export default { profileAggregate: PROFILEAGGREGATE, SEARCH, search: SEARCH, + SEARCH_NOCONTENT, + searchNoContent: SEARCH_NOCONTENT, SPELLCHECK, spellCheck: SPELLCHECK, SUGADD,