@deenruv/elasticsearch-plugin 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +23 -0
- package/README.md +122 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +20 -0
- package/lib/index.js.map +1 -0
- package/lib/src/api/api-extensions.d.ts +3 -0
- package/lib/src/api/api-extensions.js +148 -0
- package/lib/src/api/api-extensions.js.map +1 -0
- package/lib/src/api/custom-mappings.resolver.d.ts +12 -0
- package/lib/src/api/custom-mappings.resolver.js +47 -0
- package/lib/src/api/custom-mappings.resolver.js.map +1 -0
- package/lib/src/api/custom-script-fields.resolver.d.ts +12 -0
- package/lib/src/api/custom-script-fields.resolver.js +50 -0
- package/lib/src/api/custom-script-fields.resolver.js.map +1 -0
- package/lib/src/api/elasticsearch-resolver.d.ts +34 -0
- package/lib/src/api/elasticsearch-resolver.js +150 -0
- package/lib/src/api/elasticsearch-resolver.js.map +1 -0
- package/lib/src/build-elastic-body.d.ts +8 -0
- package/lib/src/build-elastic-body.js +173 -0
- package/lib/src/build-elastic-body.js.map +1 -0
- package/lib/src/constants.d.ts +3 -0
- package/lib/src/constants.js +7 -0
- package/lib/src/constants.js.map +1 -0
- package/lib/src/elasticsearch.health.d.ts +9 -0
- package/lib/src/elasticsearch.health.js +52 -0
- package/lib/src/elasticsearch.health.js.map +1 -0
- package/lib/src/elasticsearch.service.d.ts +56 -0
- package/lib/src/elasticsearch.service.js +469 -0
- package/lib/src/elasticsearch.service.js.map +1 -0
- package/lib/src/indexing/elasticsearch-index.service.d.ts +24 -0
- package/lib/src/indexing/elasticsearch-index.service.js +163 -0
- package/lib/src/indexing/elasticsearch-index.service.js.map +1 -0
- package/lib/src/indexing/indexer.controller.d.ts +98 -0
- package/lib/src/indexing/indexer.controller.js +790 -0
- package/lib/src/indexing/indexer.controller.js.map +1 -0
- package/lib/src/indexing/indexing-utils.d.ts +8 -0
- package/lib/src/indexing/indexing-utils.js +109 -0
- package/lib/src/indexing/indexing-utils.js.map +1 -0
- package/lib/src/options.d.ts +695 -0
- package/lib/src/options.js +59 -0
- package/lib/src/options.js.map +1 -0
- package/lib/src/plugin.d.ts +192 -0
- package/lib/src/plugin.js +371 -0
- package/lib/src/plugin.js.map +1 -0
- package/lib/src/types.d.ts +262 -0
- package/lib/src/types.js +17 -0
- package/lib/src/types.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.mergeWithDefaults = exports.defaultOptions = void 0;
|
|
18
|
+
const deepmerge_1 = __importDefault(require("deepmerge"));
|
|
19
|
+
exports.defaultOptions = {
|
|
20
|
+
host: "http://localhost",
|
|
21
|
+
port: 9200,
|
|
22
|
+
connectionAttempts: 10,
|
|
23
|
+
connectionAttemptInterval: 5000,
|
|
24
|
+
indexPrefix: "deenruv-",
|
|
25
|
+
indexSettings: {},
|
|
26
|
+
indexMappingProperties: {},
|
|
27
|
+
reindexProductsChunkSize: 2500,
|
|
28
|
+
reindexBulkOperationSizeLimit: 3000,
|
|
29
|
+
searchConfig: {
|
|
30
|
+
facetValueMaxSize: 50,
|
|
31
|
+
collectionMaxSize: 50,
|
|
32
|
+
totalItemsMaxSize: 10000,
|
|
33
|
+
multiMatchType: "best_fields",
|
|
34
|
+
boostFields: {
|
|
35
|
+
productName: 1,
|
|
36
|
+
productVariantName: 1,
|
|
37
|
+
description: 1,
|
|
38
|
+
sku: 1,
|
|
39
|
+
},
|
|
40
|
+
priceRangeBucketInterval: 1000,
|
|
41
|
+
mapQuery: (query) => query,
|
|
42
|
+
mapSort: (sort) => sort,
|
|
43
|
+
scriptFields: {},
|
|
44
|
+
},
|
|
45
|
+
customProductMappings: {},
|
|
46
|
+
customProductVariantMappings: {},
|
|
47
|
+
bufferUpdates: false,
|
|
48
|
+
hydrateProductRelations: [],
|
|
49
|
+
hydrateProductVariantRelations: [],
|
|
50
|
+
extendSearchInputType: {},
|
|
51
|
+
extendSearchSortType: [],
|
|
52
|
+
};
|
|
53
|
+
function mergeWithDefaults(userOptions) {
|
|
54
|
+
const { clientOptions } = userOptions, pluginOptions = __rest(userOptions, ["clientOptions"]);
|
|
55
|
+
const merged = (0, deepmerge_1.default)(exports.defaultOptions, pluginOptions);
|
|
56
|
+
return Object.assign(Object.assign({}, merged), { clientOptions });
|
|
57
|
+
}
|
|
58
|
+
exports.mergeWithDefaults = mergeWithDefaults;
|
|
59
|
+
//# sourceMappingURL=options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/options.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAWA,0DAAkC;AA0sBrB,QAAA,cAAc,GAAgC;IACzD,IAAI,EAAE,kBAAkB;IACxB,IAAI,EAAE,IAAI;IACV,kBAAkB,EAAE,EAAE;IACtB,yBAAyB,EAAE,IAAI;IAC/B,WAAW,EAAE,UAAU;IACvB,aAAa,EAAE,EAAE;IACjB,sBAAsB,EAAE,EAAE;IAC1B,wBAAwB,EAAE,IAAI;IAC9B,6BAA6B,EAAE,IAAI;IACnC,YAAY,EAAE;QACZ,iBAAiB,EAAE,EAAE;QACrB,iBAAiB,EAAE,EAAE;QACrB,iBAAiB,EAAE,KAAK;QACxB,cAAc,EAAE,aAAa;QAC7B,WAAW,EAAE;YACX,WAAW,EAAE,CAAC;YACd,kBAAkB,EAAE,CAAC;YACrB,WAAW,EAAE,CAAC;YACd,GAAG,EAAE,CAAC;SACP;QACD,wBAAwB,EAAE,IAAI;QAC9B,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK;QAC1B,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI;QACvB,YAAY,EAAE,EAAE;KACjB;IACD,qBAAqB,EAAE,EAAE;IACzB,4BAA4B,EAAE,EAAE;IAChC,aAAa,EAAE,KAAK;IACpB,uBAAuB,EAAE,EAAE;IAC3B,8BAA8B,EAAE,EAAE;IAClC,qBAAqB,EAAE,EAAE;IACzB,oBAAoB,EAAE,EAAE;CACzB,CAAC;AAEF,SAAgB,iBAAiB,CAC/B,WAAiC;IAEjC,MAAM,EAAE,aAAa,KAAuB,WAAW,EAA7B,aAAa,UAAK,WAAW,EAAjD,iBAAmC,CAAc,CAAC;IACxD,MAAM,MAAM,GAAG,IAAA,mBAAS,EACtB,sBAAc,EACd,aAAa,CACiB,CAAC;IACjC,uCAAY,MAAM,KAAE,aAAa,IAAG;AACtC,CAAC;AATD,8CASC"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { OnApplicationBootstrap } from "@nestjs/common";
|
|
2
|
+
import { EventBus, HealthCheckRegistryService, Type } from "@deenruv/core";
|
|
3
|
+
import { ElasticsearchHealthIndicator } from "./elasticsearch.health";
|
|
4
|
+
import { ElasticsearchService } from "./elasticsearch.service";
|
|
5
|
+
import { ElasticsearchIndexService } from "./indexing/elasticsearch-index.service";
|
|
6
|
+
import { ElasticsearchOptions } from "./options";
|
|
7
|
+
/**
|
|
8
|
+
* @description
|
|
9
|
+
* This plugin allows your product search to be powered by [Elasticsearch](https://github.com/elastic/elasticsearch) - a powerful Open Source search
|
|
10
|
+
* engine. This is a drop-in replacement for the DefaultSearchPlugin which exposes many powerful configuration options enabling your storefront
|
|
11
|
+
* to support a wide range of use-cases such as indexing of custom properties, fine control over search index configuration, and to leverage
|
|
12
|
+
* advanced Elasticsearch features like spacial search.
|
|
13
|
+
*
|
|
14
|
+
* ## Installation
|
|
15
|
+
*
|
|
16
|
+
* **Requires Elasticsearch v7.0 < required Elasticsearch version < 7.10 **
|
|
17
|
+
* Elasticsearch version 7.10.2 will throw error due to incompatibility with elasticsearch-js client.
|
|
18
|
+
* [Check here for more info](https://github.com/elastic/elasticsearch-js/issues/1519).
|
|
19
|
+
*
|
|
20
|
+
* `yarn add \@elastic/elasticsearch \@deenruv/elasticsearch-plugin`
|
|
21
|
+
*
|
|
22
|
+
* or
|
|
23
|
+
*
|
|
24
|
+
* `npm install \@elastic/elasticsearch \@deenruv/elasticsearch-plugin`
|
|
25
|
+
*
|
|
26
|
+
* Make sure to remove the `DefaultSearchPlugin` if it is still in the DeenruvConfig plugins array.
|
|
27
|
+
*
|
|
28
|
+
* Then add the `ElasticsearchPlugin`, calling the `.init()` method with {@link ElasticsearchOptions}:
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { ElasticsearchPlugin } from '\@deenruv/elasticsearch-plugin';
|
|
33
|
+
*
|
|
34
|
+
* const config: DeenruvConfig = {
|
|
35
|
+
* // Add an instance of the plugin to the plugins array
|
|
36
|
+
* plugins: [
|
|
37
|
+
* ElasticsearchPlugin.init({
|
|
38
|
+
* host: 'http://localhost',
|
|
39
|
+
* port: 9200,
|
|
40
|
+
* }),
|
|
41
|
+
* ],
|
|
42
|
+
* };
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* ## Search API Extensions
|
|
46
|
+
* This plugin extends the default search query of the Shop API, allowing richer querying of your product data.
|
|
47
|
+
*
|
|
48
|
+
* The [SearchResponse](/reference/graphql-api/admin/object-types/#searchresponse) type is extended with information
|
|
49
|
+
* about price ranges in the result set:
|
|
50
|
+
* ```graphql
|
|
51
|
+
* extend type SearchResponse {
|
|
52
|
+
* prices: SearchResponsePriceData!
|
|
53
|
+
* }
|
|
54
|
+
*
|
|
55
|
+
* type SearchResponsePriceData {
|
|
56
|
+
* range: PriceRange!
|
|
57
|
+
* rangeWithTax: PriceRange!
|
|
58
|
+
* buckets: [PriceRangeBucket!]!
|
|
59
|
+
* bucketsWithTax: [PriceRangeBucket!]!
|
|
60
|
+
* }
|
|
61
|
+
*
|
|
62
|
+
* type PriceRangeBucket {
|
|
63
|
+
* to: Int!
|
|
64
|
+
* count: Int!
|
|
65
|
+
* }
|
|
66
|
+
*
|
|
67
|
+
* extend input SearchInput {
|
|
68
|
+
* priceRange: PriceRangeInput
|
|
69
|
+
* priceRangeWithTax: PriceRangeInput
|
|
70
|
+
* }
|
|
71
|
+
*
|
|
72
|
+
* input PriceRangeInput {
|
|
73
|
+
* min: Int!
|
|
74
|
+
* max: Int!
|
|
75
|
+
* }
|
|
76
|
+
* ```
|
|
77
|
+
*
|
|
78
|
+
* This `SearchResponsePriceData` type allows you to query data about the range of prices in the result set.
|
|
79
|
+
*
|
|
80
|
+
* ## Example Request & Response
|
|
81
|
+
*
|
|
82
|
+
* ```graphql
|
|
83
|
+
* {
|
|
84
|
+
* search (input: {
|
|
85
|
+
* term: "table easel"
|
|
86
|
+
* groupByProduct: true
|
|
87
|
+
* priceRange: {
|
|
88
|
+
min: 500
|
|
89
|
+
max: 7000
|
|
90
|
+
}
|
|
91
|
+
* }) {
|
|
92
|
+
* totalItems
|
|
93
|
+
* prices {
|
|
94
|
+
* range {
|
|
95
|
+
* min
|
|
96
|
+
* max
|
|
97
|
+
* }
|
|
98
|
+
* buckets {
|
|
99
|
+
* to
|
|
100
|
+
* count
|
|
101
|
+
* }
|
|
102
|
+
* }
|
|
103
|
+
* items {
|
|
104
|
+
* productName
|
|
105
|
+
* score
|
|
106
|
+
* price {
|
|
107
|
+
* ...on PriceRange {
|
|
108
|
+
* min
|
|
109
|
+
* max
|
|
110
|
+
* }
|
|
111
|
+
* }
|
|
112
|
+
* }
|
|
113
|
+
* }
|
|
114
|
+
* }
|
|
115
|
+
* ```
|
|
116
|
+
*
|
|
117
|
+
* ```json
|
|
118
|
+
*{
|
|
119
|
+
* "data": {
|
|
120
|
+
* "search": {
|
|
121
|
+
* "totalItems": 9,
|
|
122
|
+
* "prices": {
|
|
123
|
+
* "range": {
|
|
124
|
+
* "min": 999,
|
|
125
|
+
* "max": 6396,
|
|
126
|
+
* },
|
|
127
|
+
* "buckets": [
|
|
128
|
+
* {
|
|
129
|
+
* "to": 1000,
|
|
130
|
+
* "count": 1
|
|
131
|
+
* },
|
|
132
|
+
* {
|
|
133
|
+
* "to": 2000,
|
|
134
|
+
* "count": 2
|
|
135
|
+
* },
|
|
136
|
+
* {
|
|
137
|
+
* "to": 3000,
|
|
138
|
+
* "count": 3
|
|
139
|
+
* },
|
|
140
|
+
* {
|
|
141
|
+
* "to": 4000,
|
|
142
|
+
* "count": 1
|
|
143
|
+
* },
|
|
144
|
+
* {
|
|
145
|
+
* "to": 5000,
|
|
146
|
+
* "count": 1
|
|
147
|
+
* },
|
|
148
|
+
* {
|
|
149
|
+
* "to": 7000,
|
|
150
|
+
* "count": 1
|
|
151
|
+
* }
|
|
152
|
+
* ]
|
|
153
|
+
* },
|
|
154
|
+
* "items": [
|
|
155
|
+
* {
|
|
156
|
+
* "productName": "Loxley Yorkshire Table Easel",
|
|
157
|
+
* "score": 30.58831,
|
|
158
|
+
* "price": {
|
|
159
|
+
* "min": 4984,
|
|
160
|
+
* "max": 4984
|
|
161
|
+
* }
|
|
162
|
+
* },
|
|
163
|
+
* // ... truncated
|
|
164
|
+
* ]
|
|
165
|
+
* }
|
|
166
|
+
* }
|
|
167
|
+
*}
|
|
168
|
+
* ```
|
|
169
|
+
*
|
|
170
|
+
* @docsCategory core plugins/ElasticsearchPlugin
|
|
171
|
+
*/
|
|
172
|
+
export declare class ElasticsearchPlugin implements OnApplicationBootstrap {
|
|
173
|
+
private eventBus;
|
|
174
|
+
private elasticsearchService;
|
|
175
|
+
private elasticsearchIndexService;
|
|
176
|
+
private elasticsearchHealthIndicator;
|
|
177
|
+
private healthCheckRegistryService;
|
|
178
|
+
private static options;
|
|
179
|
+
/** @internal */
|
|
180
|
+
constructor(eventBus: EventBus, elasticsearchService: ElasticsearchService, elasticsearchIndexService: ElasticsearchIndexService, elasticsearchHealthIndicator: ElasticsearchHealthIndicator, healthCheckRegistryService: HealthCheckRegistryService);
|
|
181
|
+
/**
|
|
182
|
+
* Set the plugin options.
|
|
183
|
+
*/
|
|
184
|
+
static init(options: ElasticsearchOptions): Type<ElasticsearchPlugin>;
|
|
185
|
+
/** @internal */
|
|
186
|
+
onApplicationBootstrap(): Promise<void>;
|
|
187
|
+
/**
|
|
188
|
+
* Returns a string representation of the target node(s) that the Elasticsearch
|
|
189
|
+
* client is configured to connect to.
|
|
190
|
+
*/
|
|
191
|
+
private nodeName;
|
|
192
|
+
}
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var ElasticsearchPlugin_1;
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.ElasticsearchPlugin = void 0;
|
|
14
|
+
const core_1 = require("@deenruv/core");
|
|
15
|
+
const operators_1 = require("rxjs/operators");
|
|
16
|
+
const api_extensions_1 = require("./api/api-extensions");
|
|
17
|
+
const custom_mappings_resolver_1 = require("./api/custom-mappings.resolver");
|
|
18
|
+
const custom_script_fields_resolver_1 = require("./api/custom-script-fields.resolver");
|
|
19
|
+
const elasticsearch_resolver_1 = require("./api/elasticsearch-resolver");
|
|
20
|
+
const constants_1 = require("./constants");
|
|
21
|
+
const elasticsearch_health_1 = require("./elasticsearch.health");
|
|
22
|
+
const elasticsearch_service_1 = require("./elasticsearch.service");
|
|
23
|
+
const elasticsearch_index_service_1 = require("./indexing/elasticsearch-index.service");
|
|
24
|
+
const indexer_controller_1 = require("./indexing/indexer.controller");
|
|
25
|
+
const options_1 = require("./options");
|
|
26
|
+
function getCustomResolvers(options) {
|
|
27
|
+
const requiresUnionResolver = 0 < Object.keys(options.customProductMappings || {}).length &&
|
|
28
|
+
0 < Object.keys(options.customProductVariantMappings || {}).length;
|
|
29
|
+
const requiresUnionScriptResolver = 0 <
|
|
30
|
+
Object.values(options.searchConfig.scriptFields || {}).filter((field) => field.context !== "product").length &&
|
|
31
|
+
0 <
|
|
32
|
+
Object.values(options.searchConfig.scriptFields || {}).filter((field) => field.context !== "variant").length;
|
|
33
|
+
return [
|
|
34
|
+
...(requiresUnionResolver ? [custom_mappings_resolver_1.CustomMappingsResolver] : []),
|
|
35
|
+
...(requiresUnionScriptResolver ? [custom_script_fields_resolver_1.CustomScriptFieldsResolver] : []),
|
|
36
|
+
];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* @description
|
|
40
|
+
* This plugin allows your product search to be powered by [Elasticsearch](https://github.com/elastic/elasticsearch) - a powerful Open Source search
|
|
41
|
+
* engine. This is a drop-in replacement for the DefaultSearchPlugin which exposes many powerful configuration options enabling your storefront
|
|
42
|
+
* to support a wide range of use-cases such as indexing of custom properties, fine control over search index configuration, and to leverage
|
|
43
|
+
* advanced Elasticsearch features like spacial search.
|
|
44
|
+
*
|
|
45
|
+
* ## Installation
|
|
46
|
+
*
|
|
47
|
+
* **Requires Elasticsearch v7.0 < required Elasticsearch version < 7.10 **
|
|
48
|
+
* Elasticsearch version 7.10.2 will throw error due to incompatibility with elasticsearch-js client.
|
|
49
|
+
* [Check here for more info](https://github.com/elastic/elasticsearch-js/issues/1519).
|
|
50
|
+
*
|
|
51
|
+
* `yarn add \@elastic/elasticsearch \@deenruv/elasticsearch-plugin`
|
|
52
|
+
*
|
|
53
|
+
* or
|
|
54
|
+
*
|
|
55
|
+
* `npm install \@elastic/elasticsearch \@deenruv/elasticsearch-plugin`
|
|
56
|
+
*
|
|
57
|
+
* Make sure to remove the `DefaultSearchPlugin` if it is still in the DeenruvConfig plugins array.
|
|
58
|
+
*
|
|
59
|
+
* Then add the `ElasticsearchPlugin`, calling the `.init()` method with {@link ElasticsearchOptions}:
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* import { ElasticsearchPlugin } from '\@deenruv/elasticsearch-plugin';
|
|
64
|
+
*
|
|
65
|
+
* const config: DeenruvConfig = {
|
|
66
|
+
* // Add an instance of the plugin to the plugins array
|
|
67
|
+
* plugins: [
|
|
68
|
+
* ElasticsearchPlugin.init({
|
|
69
|
+
* host: 'http://localhost',
|
|
70
|
+
* port: 9200,
|
|
71
|
+
* }),
|
|
72
|
+
* ],
|
|
73
|
+
* };
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* ## Search API Extensions
|
|
77
|
+
* This plugin extends the default search query of the Shop API, allowing richer querying of your product data.
|
|
78
|
+
*
|
|
79
|
+
* The [SearchResponse](/reference/graphql-api/admin/object-types/#searchresponse) type is extended with information
|
|
80
|
+
* about price ranges in the result set:
|
|
81
|
+
* ```graphql
|
|
82
|
+
* extend type SearchResponse {
|
|
83
|
+
* prices: SearchResponsePriceData!
|
|
84
|
+
* }
|
|
85
|
+
*
|
|
86
|
+
* type SearchResponsePriceData {
|
|
87
|
+
* range: PriceRange!
|
|
88
|
+
* rangeWithTax: PriceRange!
|
|
89
|
+
* buckets: [PriceRangeBucket!]!
|
|
90
|
+
* bucketsWithTax: [PriceRangeBucket!]!
|
|
91
|
+
* }
|
|
92
|
+
*
|
|
93
|
+
* type PriceRangeBucket {
|
|
94
|
+
* to: Int!
|
|
95
|
+
* count: Int!
|
|
96
|
+
* }
|
|
97
|
+
*
|
|
98
|
+
* extend input SearchInput {
|
|
99
|
+
* priceRange: PriceRangeInput
|
|
100
|
+
* priceRangeWithTax: PriceRangeInput
|
|
101
|
+
* }
|
|
102
|
+
*
|
|
103
|
+
* input PriceRangeInput {
|
|
104
|
+
* min: Int!
|
|
105
|
+
* max: Int!
|
|
106
|
+
* }
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* This `SearchResponsePriceData` type allows you to query data about the range of prices in the result set.
|
|
110
|
+
*
|
|
111
|
+
* ## Example Request & Response
|
|
112
|
+
*
|
|
113
|
+
* ```graphql
|
|
114
|
+
* {
|
|
115
|
+
* search (input: {
|
|
116
|
+
* term: "table easel"
|
|
117
|
+
* groupByProduct: true
|
|
118
|
+
* priceRange: {
|
|
119
|
+
min: 500
|
|
120
|
+
max: 7000
|
|
121
|
+
}
|
|
122
|
+
* }) {
|
|
123
|
+
* totalItems
|
|
124
|
+
* prices {
|
|
125
|
+
* range {
|
|
126
|
+
* min
|
|
127
|
+
* max
|
|
128
|
+
* }
|
|
129
|
+
* buckets {
|
|
130
|
+
* to
|
|
131
|
+
* count
|
|
132
|
+
* }
|
|
133
|
+
* }
|
|
134
|
+
* items {
|
|
135
|
+
* productName
|
|
136
|
+
* score
|
|
137
|
+
* price {
|
|
138
|
+
* ...on PriceRange {
|
|
139
|
+
* min
|
|
140
|
+
* max
|
|
141
|
+
* }
|
|
142
|
+
* }
|
|
143
|
+
* }
|
|
144
|
+
* }
|
|
145
|
+
* }
|
|
146
|
+
* ```
|
|
147
|
+
*
|
|
148
|
+
* ```json
|
|
149
|
+
*{
|
|
150
|
+
* "data": {
|
|
151
|
+
* "search": {
|
|
152
|
+
* "totalItems": 9,
|
|
153
|
+
* "prices": {
|
|
154
|
+
* "range": {
|
|
155
|
+
* "min": 999,
|
|
156
|
+
* "max": 6396,
|
|
157
|
+
* },
|
|
158
|
+
* "buckets": [
|
|
159
|
+
* {
|
|
160
|
+
* "to": 1000,
|
|
161
|
+
* "count": 1
|
|
162
|
+
* },
|
|
163
|
+
* {
|
|
164
|
+
* "to": 2000,
|
|
165
|
+
* "count": 2
|
|
166
|
+
* },
|
|
167
|
+
* {
|
|
168
|
+
* "to": 3000,
|
|
169
|
+
* "count": 3
|
|
170
|
+
* },
|
|
171
|
+
* {
|
|
172
|
+
* "to": 4000,
|
|
173
|
+
* "count": 1
|
|
174
|
+
* },
|
|
175
|
+
* {
|
|
176
|
+
* "to": 5000,
|
|
177
|
+
* "count": 1
|
|
178
|
+
* },
|
|
179
|
+
* {
|
|
180
|
+
* "to": 7000,
|
|
181
|
+
* "count": 1
|
|
182
|
+
* }
|
|
183
|
+
* ]
|
|
184
|
+
* },
|
|
185
|
+
* "items": [
|
|
186
|
+
* {
|
|
187
|
+
* "productName": "Loxley Yorkshire Table Easel",
|
|
188
|
+
* "score": 30.58831,
|
|
189
|
+
* "price": {
|
|
190
|
+
* "min": 4984,
|
|
191
|
+
* "max": 4984
|
|
192
|
+
* }
|
|
193
|
+
* },
|
|
194
|
+
* // ... truncated
|
|
195
|
+
* ]
|
|
196
|
+
* }
|
|
197
|
+
* }
|
|
198
|
+
*}
|
|
199
|
+
* ```
|
|
200
|
+
*
|
|
201
|
+
* @docsCategory core plugins/ElasticsearchPlugin
|
|
202
|
+
*/
|
|
203
|
+
let ElasticsearchPlugin = ElasticsearchPlugin_1 = class ElasticsearchPlugin {
|
|
204
|
+
/** @internal */
|
|
205
|
+
constructor(eventBus, elasticsearchService, elasticsearchIndexService, elasticsearchHealthIndicator, healthCheckRegistryService) {
|
|
206
|
+
this.eventBus = eventBus;
|
|
207
|
+
this.elasticsearchService = elasticsearchService;
|
|
208
|
+
this.elasticsearchIndexService = elasticsearchIndexService;
|
|
209
|
+
this.elasticsearchHealthIndicator = elasticsearchHealthIndicator;
|
|
210
|
+
this.healthCheckRegistryService = healthCheckRegistryService;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Set the plugin options.
|
|
214
|
+
*/
|
|
215
|
+
static init(options) {
|
|
216
|
+
this.options = (0, options_1.mergeWithDefaults)(options);
|
|
217
|
+
return ElasticsearchPlugin_1;
|
|
218
|
+
}
|
|
219
|
+
/** @internal */
|
|
220
|
+
async onApplicationBootstrap() {
|
|
221
|
+
const nodeName = this.nodeName();
|
|
222
|
+
try {
|
|
223
|
+
await this.elasticsearchService.checkConnection();
|
|
224
|
+
}
|
|
225
|
+
catch (e) {
|
|
226
|
+
core_1.Logger.error(`Could not connect to Elasticsearch instance at "${nodeName}"`, constants_1.loggerCtx);
|
|
227
|
+
core_1.Logger.error(JSON.stringify(e), constants_1.loggerCtx);
|
|
228
|
+
this.healthCheckRegistryService.registerIndicatorFunction(() => this.elasticsearchHealthIndicator.startupCheckFailed(e.message));
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
core_1.Logger.info(`Successfully connected to Elasticsearch instance at "${nodeName}"`, constants_1.loggerCtx);
|
|
232
|
+
await this.elasticsearchService.createIndicesIfNotExists();
|
|
233
|
+
this.healthCheckRegistryService.registerIndicatorFunction(() => this.elasticsearchHealthIndicator.isHealthy());
|
|
234
|
+
this.eventBus.ofType(core_1.ProductEvent).subscribe((event) => {
|
|
235
|
+
if (event.type === "deleted") {
|
|
236
|
+
return this.elasticsearchIndexService.deleteProduct(event.ctx, event.product);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
return this.elasticsearchIndexService.updateProduct(event.ctx, event.product);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
this.eventBus.ofType(core_1.ProductVariantEvent).subscribe((event) => {
|
|
243
|
+
if (event.type === "deleted") {
|
|
244
|
+
return this.elasticsearchIndexService.deleteVariant(event.ctx, event.variants);
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
return this.elasticsearchIndexService.updateVariants(event.ctx, event.variants);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
this.eventBus.ofType(core_1.AssetEvent).subscribe((event) => {
|
|
251
|
+
if (event.type === "updated") {
|
|
252
|
+
return this.elasticsearchIndexService.updateAsset(event.ctx, event.asset);
|
|
253
|
+
}
|
|
254
|
+
if (event.type === "deleted") {
|
|
255
|
+
return this.elasticsearchIndexService.deleteAsset(event.ctx, event.asset);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
this.eventBus.ofType(core_1.ProductChannelEvent).subscribe((event) => {
|
|
259
|
+
if (event.type === "assigned") {
|
|
260
|
+
return this.elasticsearchIndexService.assignProductToChannel(event.ctx, event.product, event.channelId);
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
return this.elasticsearchIndexService.removeProductFromChannel(event.ctx, event.product, event.channelId);
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
this.eventBus.ofType(core_1.ProductVariantChannelEvent).subscribe((event) => {
|
|
267
|
+
if (event.type === "assigned") {
|
|
268
|
+
return this.elasticsearchIndexService.assignVariantToChannel(event.ctx, event.productVariant.id, event.channelId);
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
return this.elasticsearchIndexService.removeVariantFromChannel(event.ctx, event.productVariant.id, event.channelId);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
// TODO: Remove this buffering logic because because we have dedicated buffering based on #1137
|
|
275
|
+
const collectionModification$ = this.eventBus.ofType(core_1.CollectionModificationEvent);
|
|
276
|
+
const closingNotifier$ = collectionModification$.pipe((0, operators_1.debounceTime)(50));
|
|
277
|
+
collectionModification$
|
|
278
|
+
.pipe((0, operators_1.buffer)(closingNotifier$), (0, operators_1.filter)((events) => 0 < events.length), (0, operators_1.map)((events) => ({
|
|
279
|
+
ctx: events[0].ctx,
|
|
280
|
+
ids: events.reduce((ids, e) => [...ids, ...e.productVariantIds], []),
|
|
281
|
+
})), (0, operators_1.filter)((e) => 0 < e.ids.length))
|
|
282
|
+
.subscribe((events) => {
|
|
283
|
+
return this.elasticsearchIndexService.updateVariantsById(events.ctx, events.ids);
|
|
284
|
+
});
|
|
285
|
+
this.eventBus
|
|
286
|
+
.ofType(core_1.TaxRateModificationEvent)
|
|
287
|
+
// The delay prevents a "TransactionNotStartedError" (in SQLite/sqljs) by allowing any existing
|
|
288
|
+
// transactions to complete before a new job is added to the queue (assuming the SQL-based
|
|
289
|
+
// JobQueueStrategy).
|
|
290
|
+
// TODO: should be able to remove owing to f0fd6625
|
|
291
|
+
.pipe((0, operators_1.delay)(1))
|
|
292
|
+
.subscribe((event) => {
|
|
293
|
+
const defaultTaxZone = event.ctx.channel.defaultTaxZone;
|
|
294
|
+
if (defaultTaxZone &&
|
|
295
|
+
(0, core_1.idsAreEqual)(defaultTaxZone.id, event.taxRate.zone.id)) {
|
|
296
|
+
return this.elasticsearchService.reindex(event.ctx);
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Returns a string representation of the target node(s) that the Elasticsearch
|
|
302
|
+
* client is configured to connect to.
|
|
303
|
+
*/
|
|
304
|
+
nodeName() {
|
|
305
|
+
const { host, port, clientOptions } = ElasticsearchPlugin_1.options;
|
|
306
|
+
const node = clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.node;
|
|
307
|
+
const nodes = clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.nodes;
|
|
308
|
+
if (nodes) {
|
|
309
|
+
return [...(Array.isArray(nodes) ? nodes : [nodes])].join(", ");
|
|
310
|
+
}
|
|
311
|
+
if (node) {
|
|
312
|
+
if (Array.isArray(node)) {
|
|
313
|
+
return node
|
|
314
|
+
.map((n) => {
|
|
315
|
+
return typeof n === "string" ? n : n.url.toString();
|
|
316
|
+
})
|
|
317
|
+
.join(", ");
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
return typeof node === "string" ? node : node.url.toString();
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return `${host}:${port}`;
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
exports.ElasticsearchPlugin = ElasticsearchPlugin;
|
|
327
|
+
exports.ElasticsearchPlugin = ElasticsearchPlugin = ElasticsearchPlugin_1 = __decorate([
|
|
328
|
+
(0, core_1.DeenruvPlugin)({
|
|
329
|
+
imports: [core_1.PluginCommonModule],
|
|
330
|
+
providers: [
|
|
331
|
+
elasticsearch_index_service_1.ElasticsearchIndexService,
|
|
332
|
+
elasticsearch_service_1.ElasticsearchService,
|
|
333
|
+
elasticsearch_health_1.ElasticsearchHealthIndicator,
|
|
334
|
+
indexer_controller_1.ElasticsearchIndexerController,
|
|
335
|
+
core_1.SearchJobBufferService,
|
|
336
|
+
{
|
|
337
|
+
provide: constants_1.ELASTIC_SEARCH_OPTIONS,
|
|
338
|
+
useFactory: () => ElasticsearchPlugin.options,
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
provide: core_1.BUFFER_SEARCH_INDEX_UPDATES,
|
|
342
|
+
useFactory: () => ElasticsearchPlugin.options.bufferUpdates === true,
|
|
343
|
+
},
|
|
344
|
+
],
|
|
345
|
+
adminApiExtensions: {
|
|
346
|
+
resolvers: () => [
|
|
347
|
+
elasticsearch_resolver_1.AdminElasticSearchResolver,
|
|
348
|
+
elasticsearch_resolver_1.EntityElasticSearchResolver,
|
|
349
|
+
...getCustomResolvers(ElasticsearchPlugin.options),
|
|
350
|
+
],
|
|
351
|
+
schema: () => (0, api_extensions_1.generateSchemaExtensions)(ElasticsearchPlugin.options),
|
|
352
|
+
},
|
|
353
|
+
shopApiExtensions: {
|
|
354
|
+
resolvers: () => [
|
|
355
|
+
elasticsearch_resolver_1.ShopElasticSearchResolver,
|
|
356
|
+
elasticsearch_resolver_1.EntityElasticSearchResolver,
|
|
357
|
+
...getCustomResolvers(ElasticsearchPlugin.options),
|
|
358
|
+
],
|
|
359
|
+
// `any` cast is there due to a strange error "Property '[Symbol.iterator]' is missing in type... URLSearchParams"
|
|
360
|
+
// which looks like possibly a TS/definitions bug.
|
|
361
|
+
schema: () => (0, api_extensions_1.generateSchemaExtensions)(ElasticsearchPlugin.options),
|
|
362
|
+
},
|
|
363
|
+
compatibility: "^0.0.0",
|
|
364
|
+
}),
|
|
365
|
+
__metadata("design:paramtypes", [core_1.EventBus,
|
|
366
|
+
elasticsearch_service_1.ElasticsearchService,
|
|
367
|
+
elasticsearch_index_service_1.ElasticsearchIndexService,
|
|
368
|
+
elasticsearch_health_1.ElasticsearchHealthIndicator,
|
|
369
|
+
core_1.HealthCheckRegistryService])
|
|
370
|
+
], ElasticsearchPlugin);
|
|
371
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/plugin.ts"],"names":[],"mappings":"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"}
|