From a6de12022978a2532eced0319898183dbd74577d Mon Sep 17 00:00:00 2001 From: Nico Hauser Date: Mon, 8 Jun 2020 16:23:52 +0200 Subject: [PATCH] feat(elasticsearch-plugin): Added mapQuery option The discussion for the feature took place in #364. This commit closes #364. --- .../src/build-elastic-body.ts | 4 +- packages/elasticsearch-plugin/src/options.ts | 49 ++++++++++++++++++- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/packages/elasticsearch-plugin/src/build-elastic-body.ts b/packages/elasticsearch-plugin/src/build-elastic-body.ts index 27f3e91cc5..d7aefd76f7 100644 --- a/packages/elasticsearch-plugin/src/build-elastic-body.ts +++ b/packages/elasticsearch-plugin/src/build-elastic-body.ts @@ -88,7 +88,9 @@ export function buildElasticBody( } } return { - query, + query: searchConfig.mapQuery + ? searchConfig.mapQuery(query, input, searchConfig, channelId, enabledOnly) + : query, sort: sortArray, from: skip || 0, size: take || 10, diff --git a/packages/elasticsearch-plugin/src/options.ts b/packages/elasticsearch-plugin/src/options.ts index 17b2a32662..764f44cb3d 100644 --- a/packages/elasticsearch-plugin/src/options.ts +++ b/packages/elasticsearch-plugin/src/options.ts @@ -1,7 +1,7 @@ -import { DeepRequired, Product, ProductVariant } from '@vendure/core'; +import { DeepRequired, ID, Product, ProductVariant } from '@vendure/core'; import deepmerge from 'deepmerge'; -import { CustomMapping } from './types'; +import { CustomMapping, ElasticSearchInput } from './types'; /** * @description @@ -188,6 +188,50 @@ export interface SearchConfig { * ``` */ 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, + channelId: ID, + enabledOnly: boolean, + ) => any; } /** @@ -246,6 +290,7 @@ export const defaultOptions: DeepRequired = { sku: 1, }, priceRangeBucketInterval: 1000, + mapQuery: (query) => query, }, customProductMappings: {}, customProductVariantMappings: {},