Support full text searches across multiple search keys, not just the sort order key.
Signed-off-by: Aramis Sennyey <sennyeya@amazon.com>
This commit is contained in:
@@ -1119,6 +1119,64 @@ describe('DefaultEntitiesCatalog', () => {
|
||||
},
|
||||
);
|
||||
|
||||
it.each(databases.eachSupportedId())(
|
||||
'should filter the text results when sortOrder is not provided, %p',
|
||||
async databaseId => {
|
||||
await createDatabase(databaseId);
|
||||
|
||||
const names = ['lion', 'cat', 'atcatss', 'dog', 'dogcat', 'aa', 's'];
|
||||
const entities: Entity[] = names.map(name =>
|
||||
// Need a stable search since default filtering is by uid, and those get generated on the fly
|
||||
// during the test case.
|
||||
entityFrom(name, { uid: name }),
|
||||
);
|
||||
|
||||
const notFoundEntities: Entity[] = [
|
||||
{
|
||||
apiVersion: 'a',
|
||||
kind: 'k',
|
||||
metadata: { name: 'something' },
|
||||
spec: {},
|
||||
},
|
||||
{
|
||||
apiVersion: 'a',
|
||||
kind: 'k',
|
||||
metadata: { name: 'something else' },
|
||||
spec: {},
|
||||
},
|
||||
];
|
||||
|
||||
await Promise.all(
|
||||
entities.concat(notFoundEntities).map(e => addEntityToSearch(e)),
|
||||
);
|
||||
|
||||
const catalog = new DefaultEntitiesCatalog({
|
||||
database: knex,
|
||||
logger: getVoidLogger(),
|
||||
stitcher,
|
||||
});
|
||||
|
||||
const filter = {
|
||||
key: 'spec.should_include_this',
|
||||
};
|
||||
|
||||
const request: QueryEntitiesInitialRequest = {
|
||||
filter,
|
||||
limit: 100,
|
||||
fullTextFilter: { term: 'cAt ', fields: ['metadata.name'] },
|
||||
};
|
||||
const response = await catalog.queryEntities(request);
|
||||
expect(response.items).toEqual([
|
||||
entityFrom('atcatss', { uid: 'atcatss' }),
|
||||
entityFrom('cat', { uid: 'cat' }),
|
||||
entityFrom('dogcat', { uid: 'dogcat' }),
|
||||
]);
|
||||
expect(response.pageInfo.nextCursor).toBeUndefined();
|
||||
expect(response.pageInfo.prevCursor).toBeUndefined();
|
||||
expect(response.totalItems).toBe(3);
|
||||
},
|
||||
);
|
||||
|
||||
it.each(databases.eachSupportedId())(
|
||||
'should include totalItems and empty entities in the response in case limit is zero, %p',
|
||||
async databaseId => {
|
||||
|
||||
@@ -51,6 +51,7 @@ import {
|
||||
} from '../database/tables';
|
||||
|
||||
import { Stitcher } from '../stitching/Stitcher';
|
||||
import { parseFullTextFilterFields } from './request/parseFullTextFilterFields';
|
||||
|
||||
import {
|
||||
isQueryEntitiesCursorRequest,
|
||||
@@ -382,11 +383,18 @@ export class DefaultEntitiesCatalog implements EntitiesCatalog {
|
||||
}
|
||||
|
||||
const normalizedFullTextFilterTerm = cursor.fullTextFilter?.term?.trim();
|
||||
const textFilterFields = cursor.fullTextFilter?.fields ?? [sortField.field];
|
||||
if (normalizedFullTextFilterTerm) {
|
||||
dbQuery.andWhereRaw(
|
||||
'value like ?',
|
||||
`%${normalizedFullTextFilterTerm.toLocaleLowerCase('en-US')}%`,
|
||||
);
|
||||
const matchQuery = db<DbSearchRow>('search')
|
||||
.select('search.entity_id')
|
||||
.whereIn('key', textFilterFields)
|
||||
.andWhere(function keyFilter() {
|
||||
this.andWhereRaw(
|
||||
'value like ?',
|
||||
`%${normalizedFullTextFilterTerm.toLocaleLowerCase('en-US')}%`,
|
||||
);
|
||||
});
|
||||
dbQuery.andWhere('search.entity_id', 'in', matchQuery);
|
||||
}
|
||||
|
||||
const countQuery = dbQuery.clone();
|
||||
|
||||
Reference in New Issue
Block a user