Skip to main content

DefaultSearchPluginInitOptions

DefaultSearchPluginInitOptions

Options which configure the behaviour of the DefaultSearchPlugin

Signature
interface DefaultSearchPluginInitOptions {
indexStockStatus?: boolean;
bufferUpdates?: boolean;
searchStrategy?: SearchStrategy;
}

indexStockStatus

property
boolean
default:
false.

If set to true, the stock status of a ProductVariant (inStock: Boolean) will be exposed in the search query results. Enabling this option on an existing Vendure installation will require a DB migration/synchronization.

bufferUpdates

property
v1.3.0
boolean
default:
false

If set to true, updates to Products, ProductVariants and Collections will not immediately trigger an update to the search index. Instead, all these changes will be buffered and will only be run via a call to the runPendingSearchIndexUpdates mutation in the Admin API.

This is very useful for installations with a large number of ProductVariants and/or Collections, as the buffering allows better control over when these expensive jobs are run, and also performs optimizations to minimize the amount of work that needs to be performed by the worker.

searchStrategy

property
v1.6.0
default:
undefined

Set a custom search strategy that implements SearchStrategy or extends an existing search strategy such as MysqlSearchStrategy, PostgresSearchStrategy or SqliteSearchStrategy.

Example

export class MySearchStrategy implements SearchStrategy {
private readonly minTermLength = 2;
private connection: TransactionalConnection;
private options: DefaultSearchPluginInitOptions;

async init(injector: Injector) {
this.connection = injector.get(TransactionalConnection);
this.options = injector.get(PLUGIN_INIT_OPTIONS);
}

async getFacetValueIds(
ctx: RequestContext,
input: SearchInput,
enabledOnly: boolean,
): Promise<Map<ID, number>> {
// ...
return createFacetIdCountMap(facetValuesResult);
}

async getCollectionIds(
ctx: RequestContext,
input: SearchInput,
enabledOnly: boolean,
): Promise<Map<ID, number>> {
// ...
return createCollectionIdCountMap(collectionsResult);
}

async getSearchResults(
ctx: RequestContext,
input: SearchInput,
enabledOnly: boolean,
): Promise<SearchResult[]> {
const take = input.take || 25;
const skip = input.skip || 0;
const sort = input.sort;
const qb = this.connection
.getRepository(SearchIndexItem)
.createQueryBuilder('si')
.select(this.createMysqlSelect(!!input.groupByProduct));
// ...

return qb
.take(take)
.skip(skip)
.getRawMany()
.then(res => res.map(r => mapToSearchResult(r, ctx.channel.currencyCode)));
}

async getTotalCount(ctx: RequestContext, input: SearchInput, enabledOnly: boolean): Promise<number> {
const innerQb = this.applyTermAndFilters(
ctx,
this.connection
.getRepository(SearchIndexItem)
.createQueryBuilder('si')
.select(this.createMysqlSelect(!!input.groupByProduct)),
input,
);
if (enabledOnly) {
innerQb.andWhere('si.enabled = :enabled', { enabled: true });
}

const totalItemsQb = this.connection.rawConnection
.createQueryBuilder()
.select('COUNT(*) as total')
.from(`(${innerQb.getQuery()})`, 'inner')
.setParameters(innerQb.getParameters());
return totalItemsQb.getRawOne().then(res => res.total);
}
}