| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- import { DeepRequired, ID, Product, ProductVariant } from '@vendure/core';
- import deepmerge from 'deepmerge';
- import { CustomMapping, ElasticSearchInput } from './types';
- /**
- * @description
- * Configuration options for the {@link ElasticsearchPlugin}.
- *
- * @docsCategory ElasticsearchPlugin
- * @docsPage ElasticsearchOptions
- */
- export interface ElasticsearchOptions {
- /**
- * @description
- * The host of the Elasticsearch server.
- */
- host: string;
- /**
- * @description
- * The port of the Elasticsearch server.
- */
- port: number;
- /**
- * @description
- * Prefix for the indices created by the plugin.
- *
- * @default
- * 'vendure-'
- */
- indexPrefix?: string;
- /**
- * @description
- * Batch size for bulk operations (e.g. when rebuilding the indices).
- *
- * @default
- * 2000
- */
- batchSize?: number;
- /**
- * @description
- * Configuration of the internal Elasticseach query.
- */
- searchConfig?: SearchConfig;
- /**
- * @description
- * Custom mappings may be defined which will add the defined data to the
- * Elasticsearch index and expose that data via the SearchResult GraphQL type,
- * adding a new `customMappings` field.
- *
- * The `graphQlType` property may be one of `String`, `Int`, `Float`, `Boolean` and
- * can be appended with a `!` to indicate non-nullable fields.
- *
- * This config option defines custom mappings which are accessible when the "groupByProduct"
- * input options is set to `true`.
- *
- * @example
- * ```TypeScript
- * customProductMappings: {
- * variantCount: {
- * graphQlType: 'Int!',
- * valueFn: (product, variants) => variants.length,
- * },
- * reviewRating: {
- * graphQlType: 'Float',
- * valueFn: product => (product.customFields as any).reviewRating,
- * },
- * }
- * ```
- *
- * @example
- * ```SDL
- * query SearchProducts($input: SearchInput!) {
- * search(input: $input) {
- * totalItems
- * items {
- * productId
- * productName
- * customMappings {
- * ...on CustomProductMappings {
- * variantCount
- * reviewRating
- * }
- * }
- * }
- * }
- * }
- * ```
- */
- customProductMappings?: {
- [fieldName: string]: CustomMapping<[Product, ProductVariant[]]>;
- };
- /**
- * @description
- * This config option defines custom mappings which are accessible when the "groupByProduct"
- * input options is set to `false`.
- *
- * @example
- * ```SDL
- * query SearchProducts($input: SearchInput!) {
- * search(input: $input) {
- * totalItems
- * items {
- * productId
- * productName
- * customMappings {
- * ...on CustomProductVariantMappings {
- * weight
- * }
- * }
- * }
- * }
- * }
- * ```
- */
- customProductVariantMappings?: {
- [fieldName: string]: CustomMapping<[ProductVariant]>;
- };
- }
- /**
- * @description
- * Configuration options for the internal Elasticsearch query which is generated when performing a search.
- *
- * @docsCategory ElasticsearchPlugin
- * @docsPage ElasticsearchOptions
- */
- export interface SearchConfig {
- /**
- * @description
- * The maximum number of FacetValues to return from the search query. Internally, this
- * value sets the "size" property of an Elasticsearch aggregation.
- *
- * @default
- * 50
- */
- facetValueMaxSize?: number;
- // prettier-ignore
- /**
- * @description
- * Defines the
- * [multi match type](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html#multi-match-types)
- * used when matching against a search term.
- *
- * @default
- * 'best_fields'
- */
- multiMatchType?: 'best_fields' | 'most_fields' | 'cross_fields' | 'phrase' | 'phrase_prefix' | 'bool_prefix';
- /**
- * @description
- * Set custom boost values for particular fields when matching against a search term.
- */
- boostFields?: BoostFieldsConfig;
- /**
- * @description
- * The interval used to group search results into buckets according to price range. For example, setting this to
- * `2000` will group into buckets every $20.00:
- *
- * ```JSON
- * {
- * "data": {
- * "search": {
- * "totalItems": 32,
- * "priceRange": {
- * "buckets": [
- * {
- * "to": 2000,
- * "count": 21
- * },
- * {
- * "to": 4000,
- * "count": 7
- * },
- * {
- * "to": 6000,
- * "count": 3
- * },
- * {
- * "to": 12000,
- * "count": 1
- * }
- * ]
- * }
- * }
- * }
- * }
- * ```
- */
- priceRangeBucketInterval?: number;
- /**
- * @description
- * This config option allows the the modification of the whole (already built) search query. This allows
- * for e.g. wildcard / fuzzy searches on the index.
- *
- * @example
- * ```TypeScript
- * mapQuery: (query, input, searchConfig, channelId, enabledOnly){
- * if(query.bool.must){
- * delete query.bool.must;
- * }
- * query.bool.should = [
- * {
- * query_string: {
- * query: "*" + term + "*",
- * fields: [
- * `productName^${searchConfig.boostFields.productName}`,
- * `productVariantName^${searchConfig.boostFields.productVariantName}`,
- * ]
- * }
- * },
- * {
- * multi_match: {
- * query: term,
- * type: searchConfig.multiMatchType,
- * fields: [
- * `description^${searchConfig.boostFields.description}`,
- * `sku^${searchConfig.boostFields.sku}`,
- * ],
- * },
- * },
- * ];
- *
- * return query;
- * }
- * ```
- */
- mapQuery?: (
- query: any,
- input: ElasticSearchInput,
- searchConfig: DeepRequired<SearchConfig>,
- channelId: ID,
- enabledOnly: boolean,
- ) => any;
- }
- /**
- * @description
- * Configuration for [boosting](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html#field-boost)
- * the scores of given fields when performing a search against a term.
- *
- * Boosting a field acts as a score multiplier for matches against that field.
- *
- * @docsCategory ElasticsearchPlugin
- * @docsPage ElasticsearchOptions
- */
- export interface BoostFieldsConfig {
- /**
- * @description
- * Defines the boost factor for the productName field.
- *
- * @default 1
- */
- productName?: number;
- /**
- * @description
- * Defines the boost factor for the productVariantName field.
- *
- * @default 1
- */
- productVariantName?: number;
- /**
- * @description
- * Defines the boost factor for the description field.
- *
- * @default 1
- */
- description?: number;
- /**
- * @description
- * Defines the boost factor for the sku field.
- *
- * @default 1
- */
- sku?: number;
- }
- export const defaultOptions: DeepRequired<ElasticsearchOptions> = {
- host: 'http://localhost',
- port: 9200,
- indexPrefix: 'vendure-',
- batchSize: 2000,
- searchConfig: {
- facetValueMaxSize: 50,
- multiMatchType: 'best_fields',
- boostFields: {
- productName: 1,
- productVariantName: 1,
- description: 1,
- sku: 1,
- },
- priceRangeBucketInterval: 1000,
- mapQuery: (query) => query,
- },
- customProductMappings: {},
- customProductVariantMappings: {},
- };
- export function mergeWithDefaults(userOptions: ElasticsearchOptions): DeepRequired<ElasticsearchOptions> {
- return deepmerge(defaultOptions, userOptions) as DeepRequired<ElasticsearchOptions>;
- }
|