You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-07 13:22:56 +03:00
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 <me@leibale.com>
This commit is contained in:
@@ -6,7 +6,6 @@ export const FIRST_KEY_INDEX = 1;
|
|||||||
export const IS_READ_ONLY = true;
|
export const IS_READ_ONLY = true;
|
||||||
|
|
||||||
export interface SearchOptions {
|
export interface SearchOptions {
|
||||||
// NOCONTENT?: true; TODO
|
|
||||||
VERBATIM?: true;
|
VERBATIM?: true;
|
||||||
NOSTOPWORDS?: true;
|
NOSTOPWORDS?: true;
|
||||||
// WITHSCORES?: true;
|
// WITHSCORES?: true;
|
||||||
|
45
packages/search/lib/commands/SEARCH_NOCONTENT.spec.ts
Normal file
45
packages/search/lib/commands/SEARCH_NOCONTENT.spec.ts
Normal file
@@ -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);
|
||||||
|
});
|
||||||
|
});
|
30
packages/search/lib/commands/SEARCH_NOCONTENT.ts
Normal file
30
packages/search/lib/commands/SEARCH_NOCONTENT.ts
Normal file
@@ -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<string>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function transformReply(reply: SearchRawReply): SearchNoContentReply {
|
||||||
|
return {
|
||||||
|
total: reply[0],
|
||||||
|
documents: reply.slice(1)
|
||||||
|
};
|
||||||
|
}
|
@@ -20,6 +20,7 @@ import * as INFO from './INFO';
|
|||||||
import * as PROFILESEARCH from './PROFILE_SEARCH';
|
import * as PROFILESEARCH from './PROFILE_SEARCH';
|
||||||
import * as PROFILEAGGREGATE from './PROFILE_AGGREGATE';
|
import * as PROFILEAGGREGATE from './PROFILE_AGGREGATE';
|
||||||
import * as SEARCH from './SEARCH';
|
import * as SEARCH from './SEARCH';
|
||||||
|
import * as SEARCH_NOCONTENT from './SEARCH_NOCONTENT';
|
||||||
import * as SPELLCHECK from './SPELLCHECK';
|
import * as SPELLCHECK from './SPELLCHECK';
|
||||||
import * as SUGADD from './SUGADD';
|
import * as SUGADD from './SUGADD';
|
||||||
import * as SUGDEL from './SUGDEL';
|
import * as SUGDEL from './SUGDEL';
|
||||||
@@ -80,6 +81,8 @@ export default {
|
|||||||
profileAggregate: PROFILEAGGREGATE,
|
profileAggregate: PROFILEAGGREGATE,
|
||||||
SEARCH,
|
SEARCH,
|
||||||
search: SEARCH,
|
search: SEARCH,
|
||||||
|
SEARCH_NOCONTENT,
|
||||||
|
searchNoContent: SEARCH_NOCONTENT,
|
||||||
SPELLCHECK,
|
SPELLCHECK,
|
||||||
spellCheck: SPELLCHECK,
|
spellCheck: SPELLCHECK,
|
||||||
SUGADD,
|
SUGADD,
|
||||||
|
Reference in New Issue
Block a user