|
@@ -23,6 +23,8 @@ import { createIndices, getClient } from './indexing-utils';
|
|
|
import { ElasticsearchOptions } from './options';
|
|
import { ElasticsearchOptions } from './options';
|
|
|
import {
|
|
import {
|
|
|
CustomMapping,
|
|
CustomMapping,
|
|
|
|
|
+ CustomScriptEnvironment,
|
|
|
|
|
+ CustomScriptMapping,
|
|
|
ElasticSearchInput,
|
|
ElasticSearchInput,
|
|
|
ElasticSearchResponse,
|
|
ElasticSearchResponse,
|
|
|
ElasticSearchResult,
|
|
ElasticSearchResult,
|
|
@@ -194,7 +196,17 @@ export class ElasticsearchService implements OnModuleInit, OnModuleDestroy {
|
|
|
totalItems,
|
|
totalItems,
|
|
|
};
|
|
};
|
|
|
} catch (e) {
|
|
} catch (e) {
|
|
|
- Logger.error(e.message, loggerCtx, e.stack);
|
|
|
|
|
|
|
+ if (e.meta.body.error.type && e.meta.body.error.type === 'search_phase_execution_exception') {
|
|
|
|
|
+ // Log runtime error of the script exception instead of stacktrace
|
|
|
|
|
+ Logger.error(
|
|
|
|
|
+ e.message,
|
|
|
|
|
+ loggerCtx,
|
|
|
|
|
+ JSON.stringify(e.meta.body.error.root_cause || [], null, 2),
|
|
|
|
|
+ );
|
|
|
|
|
+ Logger.verbose(JSON.stringify(e.meta.body.error.failed_shards || [], null, 2), loggerCtx);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Logger.error(e.message, loggerCtx, e.stack);
|
|
|
|
|
+ }
|
|
|
throw e;
|
|
throw e;
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
@@ -208,7 +220,17 @@ export class ElasticsearchService implements OnModuleInit, OnModuleDestroy {
|
|
|
totalItems: body.hits.total ? body.hits.total.value : 0,
|
|
totalItems: body.hits.total ? body.hits.total.value : 0,
|
|
|
};
|
|
};
|
|
|
} catch (e) {
|
|
} catch (e) {
|
|
|
- Logger.error(e.message, loggerCtx, e.stack);
|
|
|
|
|
|
|
+ if (e.meta.body.error.type && e.meta.body.error.type === 'search_phase_execution_exception') {
|
|
|
|
|
+ // Log runtime error of the script exception instead of stacktrace
|
|
|
|
|
+ Logger.error(
|
|
|
|
|
+ e.message,
|
|
|
|
|
+ loggerCtx,
|
|
|
|
|
+ JSON.stringify(e.meta.body.error.root_cause || [], null, 2),
|
|
|
|
|
+ );
|
|
|
|
|
+ Logger.verbose(JSON.stringify(e.meta.body.error.failed_shards || [], null, 2), loggerCtx);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Logger.error(e.message, loggerCtx, e.stack);
|
|
|
|
|
+ }
|
|
|
throw e;
|
|
throw e;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -460,6 +482,7 @@ export class ElasticsearchService implements OnModuleInit, OnModuleDestroy {
|
|
|
|
|
|
|
|
private mapVariantToSearchResult(hit: SearchHit<VariantIndexItem>): ElasticSearchResult {
|
|
private mapVariantToSearchResult(hit: SearchHit<VariantIndexItem>): ElasticSearchResult {
|
|
|
const source = hit._source;
|
|
const source = hit._source;
|
|
|
|
|
+ const fields = hit.fields;
|
|
|
const { productAsset, productVariantAsset } = this.getSearchResultAssets(source);
|
|
const { productAsset, productVariantAsset } = this.getSearchResultAssets(source);
|
|
|
const result = {
|
|
const result = {
|
|
|
...source,
|
|
...source,
|
|
@@ -480,11 +503,18 @@ export class ElasticsearchService implements OnModuleInit, OnModuleDestroy {
|
|
|
this.options.customProductVariantMappings,
|
|
this.options.customProductVariantMappings,
|
|
|
false,
|
|
false,
|
|
|
);
|
|
);
|
|
|
|
|
+ ElasticsearchService.addScriptMappings(
|
|
|
|
|
+ result,
|
|
|
|
|
+ fields,
|
|
|
|
|
+ this.options.searchConfig?.scriptFields,
|
|
|
|
|
+ 'variant',
|
|
|
|
|
+ );
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private mapProductToSearchResult(hit: SearchHit<VariantIndexItem>): ElasticSearchResult {
|
|
private mapProductToSearchResult(hit: SearchHit<VariantIndexItem>): ElasticSearchResult {
|
|
|
const source = hit._source;
|
|
const source = hit._source;
|
|
|
|
|
+ const fields = hit.fields;
|
|
|
const { productAsset, productVariantAsset } = this.getSearchResultAssets(source);
|
|
const { productAsset, productVariantAsset } = this.getSearchResultAssets(source);
|
|
|
const result = {
|
|
const result = {
|
|
|
...source,
|
|
...source,
|
|
@@ -513,6 +543,12 @@ export class ElasticsearchService implements OnModuleInit, OnModuleDestroy {
|
|
|
score: hit._score || 0,
|
|
score: hit._score || 0,
|
|
|
};
|
|
};
|
|
|
ElasticsearchService.addCustomMappings(result, source, this.options.customProductMappings, true);
|
|
ElasticsearchService.addCustomMappings(result, source, this.options.customProductMappings, true);
|
|
|
|
|
+ ElasticsearchService.addScriptMappings(
|
|
|
|
|
+ result,
|
|
|
|
|
+ fields,
|
|
|
|
|
+ this.options.searchConfig?.scriptFields,
|
|
|
|
|
+ 'product',
|
|
|
|
|
+ );
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -555,4 +591,34 @@ export class ElasticsearchService implements OnModuleInit, OnModuleDestroy {
|
|
|
}
|
|
}
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ private static addScriptMappings(
|
|
|
|
|
+ result: any,
|
|
|
|
|
+ fields: any,
|
|
|
|
|
+ mappings: { [fieldName: string]: CustomScriptMapping<any> },
|
|
|
|
|
+ environment: CustomScriptEnvironment,
|
|
|
|
|
+ ): any {
|
|
|
|
|
+ const customMappings = Object.keys(mappings || {});
|
|
|
|
|
+ if (customMappings.length) {
|
|
|
|
|
+ const customScriptFieldsResult: any = {};
|
|
|
|
|
+ for (const name of customMappings) {
|
|
|
|
|
+ const env = mappings[name].environment;
|
|
|
|
|
+ if (env === environment || env === 'both') {
|
|
|
|
|
+ const fieldVal = (fields as any)[name] || undefined;
|
|
|
|
|
+ if (Array.isArray(fieldVal)) {
|
|
|
|
|
+ if (fieldVal.length === 1) {
|
|
|
|
|
+ customScriptFieldsResult[name] = fieldVal[0];
|
|
|
|
|
+ }
|
|
|
|
|
+ if (fieldVal.length > 1) {
|
|
|
|
|
+ customScriptFieldsResult[name] = JSON.stringify(fieldVal);
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ customScriptFieldsResult[name] = fieldVal;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ (result as any).customScriptFields = customScriptFieldsResult;
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|