Refactored config/options based on feedback

Signed-off-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com>
This commit is contained in:
Andre Wanlin
2022-06-21 14:29:45 -05:00
committed by Fredrik Adelöw
parent a678795d25
commit 90aca31689
8 changed files with 65 additions and 42 deletions
+1 -1
View File
@@ -39,7 +39,7 @@ async function createSearchEngine(
}
if (await PgSearchEngine.supported(env.database)) {
return await PgSearchEngine.from({
return await PgSearchEngine.fromConfig({
database: env.database,
config: env.config,
});
@@ -13,8 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ConfigReader } from '@backstage/config';
import { DatabaseStore } from '../database';
import { PgSearchHighlightConfig } from '../types';
import { PgSearchHighlightOptions } from '../types';
import {
ConcretePgSearchQuery,
decodePageCursor,
@@ -23,7 +24,7 @@ import {
} from './PgSearchEngine';
import { PgSearchEngineIndexer } from './PgSearchEngineIndexer';
const highlightOptions: PgSearchHighlightConfig = {
const highlightOptions: PgSearchHighlightOptions = {
preTag: '<tag>',
postTag: '</tag>',
useHighlight: true,
@@ -47,6 +48,13 @@ describe('PgSearchEngine', () => {
const tx: any = {} as any;
let searchEngine: PgSearchEngine;
let database: jest.Mocked<DatabaseStore>;
const config = {
search: {
pg: {
highlightOptions,
},
},
};
beforeEach(() => {
database = {
@@ -57,7 +65,7 @@ describe('PgSearchEngine', () => {
completeInsert: jest.fn(),
prepareInsert: jest.fn(),
};
searchEngine = new PgSearchEngine(database);
searchEngine = new PgSearchEngine(database, new ConfigReader(config));
});
describe('translator', () => {
@@ -28,7 +28,7 @@ import {
} from '../database';
import { v4 as uuid } from 'uuid';
import { Config } from '@backstage/config';
import { PgSearchHighlightConfig, PgSearchHighlightOptions } from '../types';
import { PgSearchHighlightOptions, PgSearchOptions } from '../types';
export type ConcretePgSearchQuery = {
pgQuery: PgSearchQuery;
@@ -36,36 +36,46 @@ export type ConcretePgSearchQuery = {
};
export class PgSearchEngine implements SearchEngine {
private readonly highlightOptions: PgSearchHighlightConfig;
constructor(
private readonly databaseStore: DatabaseStore,
highlightOptions?: PgSearchHighlightOptions,
) {
private readonly highlightOptions: PgSearchHighlightOptions;
constructor(private readonly databaseStore: DatabaseStore, config: Config) {
const uuidTag = uuid();
this.highlightOptions = {
const highlightConfig = config.getOptionalConfig(
'search.pg.highlightOptions',
);
const highlightOptions: PgSearchHighlightOptions = {
preTag: `<${uuidTag}>`,
postTag: `</${uuidTag}>`,
useHighlight: true,
maxWords: 35,
minWords: 15,
shortWord: 3,
highlightAll: false,
maxFragments: 0,
fragmentDelimiter: ' ... ',
...highlightOptions,
useHighlight: highlightConfig?.getOptionalBoolean('useHighlight') ?? true,
maxWords: highlightConfig?.getOptionalNumber('maxWords') ?? 35,
minWords: highlightConfig?.getOptionalNumber('minWords') ?? 15,
shortWord: highlightConfig?.getOptionalNumber('shortWord') ?? 3,
highlightAll:
highlightConfig?.getOptionalBoolean('highlightAll') ?? false,
maxFragments: highlightConfig?.getOptionalNumber('maxFragments') ?? 0,
fragmentDelimiter:
highlightConfig?.getOptionalString('fragmentDelimiter') ?? ' ... ',
};
this.highlightOptions = highlightOptions;
}
/**
* @deprecated This will be removed in a future release, please us fromConfig instead
*/
static async from(options: {
database: PluginDatabaseManager;
config: Config;
}): Promise<PgSearchEngine> {
return new PgSearchEngine(
await DatabaseDocumentStore.create(await options.database.getClient()),
options.config.getOptional<PgSearchHighlightOptions>(
'search.pg.highlightOptions',
),
options.config,
);
}
static async fromConfig({ config, database }: PgSearchOptions) {
return new PgSearchEngine(
await DatabaseDocumentStore.create(await database.getClient()),
config,
);
}
@@ -75,7 +85,7 @@ export class PgSearchEngine implements SearchEngine {
translator(
query: SearchQuery,
options: PgSearchHighlightConfig,
options: PgSearchHighlightOptions,
): ConcretePgSearchQuery {
const pageSize = 25;
const { page } = decodePageCursor(query.pageCursor);
@@ -15,10 +15,10 @@
*/
import { TestDatabaseId, TestDatabases } from '@backstage/backend-test-utils';
import { IndexableDocument } from '@backstage/plugin-search-common';
import { PgSearchHighlightConfig } from '../types';
import { PgSearchHighlightOptions } from '../types';
import { DatabaseDocumentStore } from './DatabaseDocumentStore';
const highlightOptions: PgSearchHighlightConfig = {
const highlightOptions: PgSearchHighlightOptions = {
preTag: '<tag>',
postTag: '</tag>',
useHighlight: false,
@@ -132,8 +132,9 @@ export class DatabaseDocumentStore implements DatabaseStore {
async query(
tx: Knex.Transaction,
{ types, pgTerm, fields, offset, limit, options }: PgSearchQuery,
searchQuery: PgSearchQuery,
): Promise<DocumentResultRow[]> {
const { types, pgTerm, fields, offset, limit, options } = searchQuery;
// Builds a query like:
// SELECT ts_rank_cd(body, query) AS rank, type, document,
// ts_headline('english', document, query) AS highlight
@@ -15,7 +15,7 @@
*/
import { IndexableDocument } from '@backstage/plugin-search-common';
import { Knex } from 'knex';
import { PgSearchHighlightConfig } from '../types';
import { PgSearchHighlightOptions } from '../types';
export interface PgSearchQuery {
fields?: Record<string, string | string[]>;
@@ -23,7 +23,7 @@ export interface PgSearchQuery {
pgTerm?: string;
offset: number;
limit: number;
options: PgSearchHighlightConfig;
options: PgSearchHighlightOptions;
}
export interface DatabaseStore {
@@ -22,3 +22,4 @@
export * from './database';
export * from './PgSearchEngine';
export type { PgSearchHighlightOptions } from './types';
+16 -13
View File
@@ -14,6 +14,22 @@
* limitations under the License.
*/
import { PluginDatabaseManager } from '@backstage/backend-common';
import { Config } from '@backstage/config';
/**
* Options to instantiate PgSearchEngine
* @public
*/
export type PgSearchOptions = {
config: Config;
database: PluginDatabaseManager;
};
/**
* Options for highlighting search terms
* @public
*/
export type PgSearchHighlightOptions = {
useHighlight?: boolean;
maxWords?: number;
@@ -22,19 +38,6 @@ export type PgSearchHighlightOptions = {
highlightAll?: boolean;
maxFragments?: number;
fragmentDelimiter?: string;
};
/**
* @public
*/
export type PgSearchHighlightConfig = {
useHighlight: boolean;
maxWords: number;
minWords: number;
shortWord: number;
highlightAll: boolean;
maxFragments: number;
fragmentDelimiter: string;
preTag: string;
postTag: string;
};