lemon-core 3.1.0 → 3.1.1
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/README.md +1 -0
- package/dist/controllers/dummy-controller.d.ts +1 -1
- package/dist/controllers/dummy-controller.js +2 -2
- package/dist/controllers/dummy-controller.js.map +1 -1
- package/dist/controllers/general-api-controller.d.ts +1 -1
- package/dist/cores/api/api-service.d.ts +239 -0
- package/dist/cores/api/api-service.js +674 -0
- package/dist/cores/api/api-service.js.map +1 -0
- package/dist/cores/api/index.d.ts +10 -0
- package/dist/cores/api/index.js +27 -0
- package/dist/cores/api/index.js.map +1 -0
- package/dist/cores/aws/aws-kms-service.d.ts +53 -2
- package/dist/cores/aws/aws-kms-service.js +104 -17
- package/dist/cores/aws/aws-kms-service.js.map +1 -1
- package/dist/cores/cache/cache-service.d.ts +440 -0
- package/dist/cores/cache/cache-service.js +967 -0
- package/dist/cores/cache/cache-service.js.map +1 -0
- package/dist/cores/cache/index.d.ts +10 -0
- package/dist/cores/cache/index.js +27 -0
- package/dist/cores/cache/index.js.map +1 -0
- package/dist/cores/cache-service.d.ts +54 -18
- package/dist/cores/cache-service.js +37 -26
- package/dist/cores/cache-service.js.map +1 -1
- package/dist/cores/core-types.d.ts +42 -12
- package/dist/cores/dynamo/dynamo-query-service.d.ts +52 -0
- package/dist/cores/dynamo/dynamo-query-service.js +127 -0
- package/dist/cores/dynamo/dynamo-query-service.js.map +1 -0
- package/dist/cores/dynamo/dynamo-scan-service.d.ts +70 -0
- package/dist/cores/dynamo/dynamo-scan-service.js +164 -0
- package/dist/cores/dynamo/dynamo-scan-service.js.map +1 -0
- package/dist/cores/dynamo/dynamo-service.d.ts +192 -0
- package/dist/cores/dynamo/dynamo-service.js +525 -0
- package/dist/cores/dynamo/dynamo-service.js.map +1 -0
- package/dist/cores/dynamo/index.d.ts +12 -0
- package/dist/cores/dynamo/index.js +29 -0
- package/dist/cores/dynamo/index.js.map +1 -0
- package/dist/cores/elastic/elastic6-query-service.d.ts +104 -0
- package/dist/cores/elastic/elastic6-query-service.js +510 -0
- package/dist/cores/elastic/elastic6-query-service.js.map +1 -0
- package/dist/cores/elastic/elastic6-service.d.ts +273 -0
- package/dist/cores/elastic/elastic6-service.js +903 -0
- package/dist/cores/elastic/elastic6-service.js.map +1 -0
- package/dist/cores/elastic/hangul-service.d.ts +102 -0
- package/dist/cores/elastic/hangul-service.js +205 -0
- package/dist/cores/elastic/hangul-service.js.map +1 -0
- package/dist/cores/elastic/index.d.ts +12 -0
- package/dist/cores/elastic/index.js +29 -0
- package/dist/cores/elastic/index.js.map +1 -0
- package/dist/cores/hangul-service.d.ts +17 -3
- package/dist/cores/hangul-service.js +17 -8
- package/dist/cores/hangul-service.js.map +1 -1
- package/dist/cores/index.d.ts +5 -11
- package/dist/cores/index.js +8 -13
- package/dist/cores/index.js.map +1 -1
- package/dist/cores/lambda/lambda-dynamo-stream-handler.d.ts +2 -2
- package/dist/cores/lambda/lambda-web-handler.d.ts +158 -8
- package/dist/cores/lambda/lambda-web-handler.js +283 -77
- package/dist/cores/lambda/lambda-web-handler.js.map +1 -1
- package/dist/cores/protocol/protocol-service.d.ts +4 -0
- package/dist/cores/protocol/protocol-service.js +12 -7
- package/dist/cores/protocol/protocol-service.js.map +1 -1
- package/dist/cores/storage/http-storage-service.d.ts +22 -0
- package/dist/cores/storage/http-storage-service.js +129 -0
- package/dist/cores/storage/http-storage-service.js.map +1 -0
- package/dist/cores/storage/index.d.ts +14 -0
- package/dist/cores/storage/index.js +31 -0
- package/dist/cores/storage/index.js.map +1 -0
- package/dist/cores/storage/model-manager.d.ts +93 -0
- package/dist/cores/storage/model-manager.js +192 -0
- package/dist/cores/storage/model-manager.js.map +1 -0
- package/dist/cores/storage/proxy-storage-service.d.ts +573 -0
- package/dist/cores/storage/proxy-storage-service.js +913 -0
- package/dist/cores/storage/proxy-storage-service.js.map +1 -0
- package/dist/cores/storage/redis-storage-service.d.ts +183 -0
- package/dist/cores/storage/redis-storage-service.js +391 -0
- package/dist/cores/storage/redis-storage-service.js.map +1 -0
- package/dist/cores/storage/storage-service.d.ts +169 -0
- package/dist/cores/storage/storage-service.js +374 -0
- package/dist/cores/storage/storage-service.js.map +1 -0
- package/dist/cores/storage-service.d.ts +1 -1
- package/dist/cores/storage-service.js +2 -2
- package/dist/cores/storage-service.js.map +1 -1
- package/dist/engine/utilities.d.ts +4 -3
- package/dist/engine/utilities.js +6 -6
- package/dist/engine/utilities.js.map +1 -1
- package/dist/environ.d.ts +2 -2
- package/dist/environ.js +7 -4
- package/dist/environ.js.map +1 -1
- package/dist/extended/abstract-service.d.ts +533 -0
- package/dist/extended/abstract-service.js +915 -0
- package/dist/extended/abstract-service.js.map +1 -0
- package/dist/extended/index.d.ts +10 -0
- package/dist/extended/index.js +27 -0
- package/dist/extended/index.js.map +1 -0
- package/dist/helpers/helpers.d.ts +7 -0
- package/dist/helpers/helpers.js +7 -0
- package/dist/helpers/helpers.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/package.json +6 -4
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { GeneralItem, Elastic6SimpleQueriable, QueryResult, SimpleSearchParam, AutocompleteSearchParam, SearchBody } from '../core-types';
|
|
2
|
+
import { Elastic6Service, SearchType } from './elastic6-service';
|
|
3
|
+
/**
|
|
4
|
+
* class: `Elastic6QueryService`
|
|
5
|
+
* - support simple query like range search.
|
|
6
|
+
*/
|
|
7
|
+
export declare class Elastic6QueryService<T extends GeneralItem> implements Elastic6SimpleQueriable<T> {
|
|
8
|
+
protected readonly service: Elastic6Service;
|
|
9
|
+
/**
|
|
10
|
+
* use query w/ the given search-service.
|
|
11
|
+
* @param service the origin search-service to use.
|
|
12
|
+
*/
|
|
13
|
+
constructor(service: Elastic6Service);
|
|
14
|
+
/**
|
|
15
|
+
* get options
|
|
16
|
+
*/
|
|
17
|
+
protected get options(): import("./elastic6-service").Elastic6Option;
|
|
18
|
+
/**
|
|
19
|
+
* say hello of identity.
|
|
20
|
+
*/
|
|
21
|
+
hello: () => string;
|
|
22
|
+
/**
|
|
23
|
+
* query all by id.
|
|
24
|
+
*
|
|
25
|
+
* @param id
|
|
26
|
+
* @param limit
|
|
27
|
+
* @param isDesc
|
|
28
|
+
*/
|
|
29
|
+
queryAll(id: string, limit?: number, isDesc?: boolean): Promise<QueryResult<T>>;
|
|
30
|
+
/**
|
|
31
|
+
* search in simple mode
|
|
32
|
+
* - 기본적으로 'mini-language'를 그대로 지원하도록한다.
|
|
33
|
+
* - 입력의 파라마터의 키값은 테스트할 필드들이다.
|
|
34
|
+
* {"stock":">1"} => query_string : "stock:>1"
|
|
35
|
+
*
|
|
36
|
+
* - 파라미터 예약:
|
|
37
|
+
* $query : ES _search 용 쿼리를 그대로 이용.
|
|
38
|
+
* $exist : 'a,!b,c' => a AND NOT b AND c 를 _exists_ 항목으로 풀어씀.
|
|
39
|
+
* $source : _source 항목에 포함될 내용. (undefined => _source:false)
|
|
40
|
+
* $limit : same as "size"
|
|
41
|
+
* $page : same as "from" / "size" ($limit 를 ipp 으로 함축하여 이용).
|
|
42
|
+
*
|
|
43
|
+
*
|
|
44
|
+
*
|
|
45
|
+
* [Mini-Language]
|
|
46
|
+
* ```
|
|
47
|
+
* # find title field which contains quick or brown.
|
|
48
|
+
* title:(quick OR brown)
|
|
49
|
+
*
|
|
50
|
+
* # not-null value.
|
|
51
|
+
* _exists_:title
|
|
52
|
+
*
|
|
53
|
+
* # regular exp.
|
|
54
|
+
* name:/joh?n(ath[oa]n)/
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
*
|
|
58
|
+
* 참고: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax
|
|
59
|
+
* 참고: http://okfnlabs.org/blog/2013/07/01/elasticsearch-query-tutorial.html
|
|
60
|
+
*
|
|
61
|
+
* @param param search param
|
|
62
|
+
*/
|
|
63
|
+
searchSimple(param: SimpleSearchParam): Promise<QueryResult<T>>;
|
|
64
|
+
/**
|
|
65
|
+
* search with raw query language.
|
|
66
|
+
*
|
|
67
|
+
* @param body SearchBody.
|
|
68
|
+
* @returns results.
|
|
69
|
+
*/
|
|
70
|
+
search(body: SearchBody, searchType?: SearchType): Promise<any>;
|
|
71
|
+
/**
|
|
72
|
+
* convert result as `QueryResult`
|
|
73
|
+
* @param body the query body requested
|
|
74
|
+
* @param res the result
|
|
75
|
+
* @returns QueryResult
|
|
76
|
+
*/
|
|
77
|
+
asQueryResult(body: SearchBody, res: any): QueryResult<T>;
|
|
78
|
+
/**
|
|
79
|
+
* convert `AutocompleteSearchParam` to `SearchBody`
|
|
80
|
+
* @param param AutocompleteSearchParam
|
|
81
|
+
* @returns SearchBody
|
|
82
|
+
*/
|
|
83
|
+
asSearchBody(param: AutocompleteSearchParam): {
|
|
84
|
+
field: string;
|
|
85
|
+
query: string;
|
|
86
|
+
body: SearchBody;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* search item in Search-as-You-Type way
|
|
90
|
+
* @param param AutocompleteSearchParam
|
|
91
|
+
*/
|
|
92
|
+
searchAutocomplete(param: AutocompleteSearchParam): Promise<{
|
|
93
|
+
list: T[];
|
|
94
|
+
total?: number;
|
|
95
|
+
page?: number;
|
|
96
|
+
limit?: number;
|
|
97
|
+
aggregations?: any;
|
|
98
|
+
last?: any;
|
|
99
|
+
}>;
|
|
100
|
+
/**
|
|
101
|
+
* build query parameter from search param.
|
|
102
|
+
*/
|
|
103
|
+
buildQueryBody: (param: SimpleSearchParam) => SearchBody;
|
|
104
|
+
}
|
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.Elastic6QueryService = void 0;
|
|
16
|
+
/**
|
|
17
|
+
* `elastic6-query-service.ts`
|
|
18
|
+
* - common service to query with id via elastic6
|
|
19
|
+
*
|
|
20
|
+
*
|
|
21
|
+
* @author Steve Jung <steve@lemoncloud.io>
|
|
22
|
+
* @date 2019-11-20 initial version via backbone
|
|
23
|
+
* @date 2021-12-07 support SearchBody
|
|
24
|
+
*
|
|
25
|
+
* @copyright (C) 2019 LemonCloud Co Ltd. - All Rights Reserved.
|
|
26
|
+
*/
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
28
|
+
const engine_1 = require("../../engine/");
|
|
29
|
+
const elastic6_service_1 = require("./elastic6-service");
|
|
30
|
+
const hangul_service_1 = __importDefault(require("./hangul-service"));
|
|
31
|
+
const NS = engine_1.$U.NS('ES6Q', 'green'); // NAMESPACE TO BE PRINTED.
|
|
32
|
+
/**
|
|
33
|
+
* class: `Elastic6QueryService`
|
|
34
|
+
* - support simple query like range search.
|
|
35
|
+
*/
|
|
36
|
+
class Elastic6QueryService {
|
|
37
|
+
/**
|
|
38
|
+
* use query w/ the given search-service.
|
|
39
|
+
* @param service the origin search-service to use.
|
|
40
|
+
*/
|
|
41
|
+
constructor(service) {
|
|
42
|
+
/**
|
|
43
|
+
* say hello of identity.
|
|
44
|
+
*/
|
|
45
|
+
this.hello = () => `elastic6-query-service:${this.options.indexName}`;
|
|
46
|
+
/**
|
|
47
|
+
* build query parameter from search param.
|
|
48
|
+
*/
|
|
49
|
+
this.buildQueryBody = (param) => {
|
|
50
|
+
//! parameters.
|
|
51
|
+
let $query = null;
|
|
52
|
+
let $source = null;
|
|
53
|
+
let $page = -1;
|
|
54
|
+
let $limit = -1;
|
|
55
|
+
let $A = ''; // Aggregation
|
|
56
|
+
let $O = ''; // OrderBy
|
|
57
|
+
let $H = ''; // Highlight
|
|
58
|
+
//! build query.
|
|
59
|
+
const queries = Object.keys(param).reduce((list, key) => {
|
|
60
|
+
let val = param[key];
|
|
61
|
+
// ignore internal values.
|
|
62
|
+
if (key.startsWith('_'))
|
|
63
|
+
return list;
|
|
64
|
+
// _log(NS, `>> param[${key}] = `, val);
|
|
65
|
+
if (key === '$query') {
|
|
66
|
+
$query = {
|
|
67
|
+
query: typeof val === 'object' ? val : typeof val === 'string' ? JSON.parse(val) : `${val || ''}`,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
else if (key === '$limit') {
|
|
71
|
+
$limit = engine_1.$U.N(val, 0);
|
|
72
|
+
}
|
|
73
|
+
else if (key === '$page') {
|
|
74
|
+
$page = engine_1.$U.N(val, 0);
|
|
75
|
+
}
|
|
76
|
+
else if (key === '$Q') {
|
|
77
|
+
if (!val) {
|
|
78
|
+
//NOP;
|
|
79
|
+
}
|
|
80
|
+
else if (typeof val === 'object') {
|
|
81
|
+
// ONLY IF object. use it as raw query.
|
|
82
|
+
$query = val;
|
|
83
|
+
}
|
|
84
|
+
else if (typeof val === 'string' && val.startsWith('{') && val.endsWith('}')) {
|
|
85
|
+
// might be the json data.
|
|
86
|
+
$query = JSON.parse(val);
|
|
87
|
+
}
|
|
88
|
+
else if (typeof val === 'string') {
|
|
89
|
+
// might be query string.
|
|
90
|
+
//! escape queries..
|
|
91
|
+
// + - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /
|
|
92
|
+
// val = val.replace(/([\(\)])/ig,'\\$1'); //TODO - 이걸 무시하면, 중복 조건 검색에 문제가 생김, 하여 일단 안하는걸루. @180828.
|
|
93
|
+
list.push(`(${val})`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else if (key === '$A') {
|
|
97
|
+
$A = `${val}`.trim(); // ',' delimited terms to count
|
|
98
|
+
}
|
|
99
|
+
else if (key === '$O') {
|
|
100
|
+
$O = `${val}`.trim(); // ',' delimited terms to order
|
|
101
|
+
}
|
|
102
|
+
else if (key === '$H') {
|
|
103
|
+
$H = `${val}`.trim(); // ',' delimited terms to highlight
|
|
104
|
+
}
|
|
105
|
+
else if (key === '$source') {
|
|
106
|
+
// returned source fields set. '*', 'obj.*', '!abc'
|
|
107
|
+
if (val === '*') {
|
|
108
|
+
// all.
|
|
109
|
+
$source = '*';
|
|
110
|
+
}
|
|
111
|
+
else if (typeof val === 'string' && val.indexOf !== undefined) {
|
|
112
|
+
// string array set.
|
|
113
|
+
const vals = val.split(',') || [];
|
|
114
|
+
const $includes = [];
|
|
115
|
+
const $excludes = [];
|
|
116
|
+
vals.forEach(val => {
|
|
117
|
+
val = `${val || ''}`.trim();
|
|
118
|
+
if (!val)
|
|
119
|
+
return;
|
|
120
|
+
if (val.startsWith('!')) {
|
|
121
|
+
$excludes.push(val.substr(1));
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
$includes.push(val);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
$source = { includes: $includes, excludes: $excludes };
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
$source = val;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
else if (key === '$exist' || key === '$exists') {
|
|
134
|
+
(Array.isArray(val) ? val : `${val}`.split(',') || []).forEach((val) => {
|
|
135
|
+
val = `${val || ''}`.trim();
|
|
136
|
+
if (!val)
|
|
137
|
+
return;
|
|
138
|
+
if (val.startsWith('!')) {
|
|
139
|
+
list.push('NOT _exists_:' + val.substr(1));
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
list.push('_exists_:' + val);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
//! escape if there is ' ' except like '(a AND B)'
|
|
148
|
+
const escape_val = (val) => {
|
|
149
|
+
if (typeof val === 'string' && val === '') {
|
|
150
|
+
return '"' + val + '"';
|
|
151
|
+
}
|
|
152
|
+
else if (val && typeof val === 'string') {
|
|
153
|
+
if (val.startsWith('(') && val.endsWith(')')) {
|
|
154
|
+
// nop
|
|
155
|
+
}
|
|
156
|
+
else if (val.startsWith('"') && val.endsWith('"')) {
|
|
157
|
+
// must be string block
|
|
158
|
+
return val;
|
|
159
|
+
}
|
|
160
|
+
else if (val.indexOf(',') > 0) {
|
|
161
|
+
// list of array.
|
|
162
|
+
return val.split(',').map(s => {
|
|
163
|
+
return (s || '').trim();
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
else if (
|
|
167
|
+
// special chars
|
|
168
|
+
val.indexOf(' ') >= 0 ||
|
|
169
|
+
val.indexOf('\n') >= 0 ||
|
|
170
|
+
val.indexOf(':') >= 0 ||
|
|
171
|
+
val.indexOf('\\') >= 0 ||
|
|
172
|
+
val.indexOf('#') >= 0 ||
|
|
173
|
+
val.indexOf('^') >= 0) {
|
|
174
|
+
const str = val.replace(/([\"\'])/gi, '\\$1'); // replace '"' -> '\"'
|
|
175
|
+
return '"' + str + '"';
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return val;
|
|
179
|
+
};
|
|
180
|
+
val = escape_val(val);
|
|
181
|
+
//! add to query-list.
|
|
182
|
+
if (key.startsWith('!')) {
|
|
183
|
+
if (val) {
|
|
184
|
+
if (Array.isArray(val)) {
|
|
185
|
+
const vals = val.map((_) => escape_val(_));
|
|
186
|
+
list.push(key.substr(1) + ':(NOT (' + vals.join(' OR ') + '))');
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
list.push(key.substr(1) + ':(NOT ' + val + ')');
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
list.push('_exists_:' + key.substr(1));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
else if (key.startsWith('#')) {
|
|
197
|
+
// projection.
|
|
198
|
+
$source = $source || { includes: [], excludes: [] };
|
|
199
|
+
if ($source && $source.includes) {
|
|
200
|
+
$source.includes.push(key.substr(1));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
else if (val === undefined) {
|
|
204
|
+
//! nop
|
|
205
|
+
}
|
|
206
|
+
else if (val && Array.isArray(val)) {
|
|
207
|
+
// list.push('(' + val.map(val => `${key}:${val}`).join(' OR ') + ')');
|
|
208
|
+
list.push(`${key}:` + '(' + val.map((val) => `${escape_val(val)}`).join(' OR ') + ')');
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
list.push(`${key}:${val}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return list;
|
|
215
|
+
}, []);
|
|
216
|
+
//! prepare returned body.
|
|
217
|
+
const $body = $query
|
|
218
|
+
? $query
|
|
219
|
+
: (queries.length && { query: { query_string: { query: queries.join(' AND ') } } }) || {}; // $query 이게 있으면 그냥 이걸 이용.
|
|
220
|
+
//! Aggregation.
|
|
221
|
+
if ($A) {
|
|
222
|
+
// const $aggs = {
|
|
223
|
+
// // "types_count" : { "value_count" : { "field" : "brand" } }
|
|
224
|
+
// "types_count" : { "terms" : { "field" : "brand" } }
|
|
225
|
+
// }
|
|
226
|
+
const $aggs = $A.split(',').reduce(($a, val) => {
|
|
227
|
+
val = ('' + val).trim();
|
|
228
|
+
if (val) {
|
|
229
|
+
if (val.indexOf(':') > 0) {
|
|
230
|
+
// must be size.
|
|
231
|
+
const [nm, size] = val.split(':', 2);
|
|
232
|
+
$a[nm] = { terms: { field: nm, size: parseInt(size) } };
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
$a[val] = { terms: { field: val } };
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return $a;
|
|
239
|
+
}, {});
|
|
240
|
+
$body['aggs'] = $aggs;
|
|
241
|
+
}
|
|
242
|
+
//! OrderBy.
|
|
243
|
+
if ($O) {
|
|
244
|
+
//see sorting: see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html.
|
|
245
|
+
const $sort = $O.split(',').reduce(($a, val) => {
|
|
246
|
+
val = ('' + val).trim();
|
|
247
|
+
if (val) {
|
|
248
|
+
let name = val;
|
|
249
|
+
let asc = true;
|
|
250
|
+
if (val.startsWith('!')) {
|
|
251
|
+
// reverse
|
|
252
|
+
name = val.slice(1);
|
|
253
|
+
asc = false;
|
|
254
|
+
}
|
|
255
|
+
if (name) {
|
|
256
|
+
$a.push({ [name]: { order: asc ? 'asc' : 'desc' } });
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return $a;
|
|
260
|
+
}, []);
|
|
261
|
+
if ($sort.length) {
|
|
262
|
+
$body.sort = $sort;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
//! Highlight.
|
|
266
|
+
if ($H) {
|
|
267
|
+
const $highlight = $H.split(',').reduce(($h, val) => {
|
|
268
|
+
val = ('' + val).trim();
|
|
269
|
+
if (val) {
|
|
270
|
+
$h[val] = { type: 'unified' };
|
|
271
|
+
}
|
|
272
|
+
return $h;
|
|
273
|
+
}, {});
|
|
274
|
+
$body['highlight'] = {};
|
|
275
|
+
$body['highlight']['fields'] = $highlight;
|
|
276
|
+
}
|
|
277
|
+
//! if valid limit, then paginating.
|
|
278
|
+
if ($limit > -1) {
|
|
279
|
+
$body.size = $limit;
|
|
280
|
+
if ($page > -1) {
|
|
281
|
+
// starts from 0
|
|
282
|
+
$body.from = $page * $limit;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
//! field projection with _source parameter.
|
|
286
|
+
if ($source !== null)
|
|
287
|
+
$body._source = $source;
|
|
288
|
+
//! returns body.
|
|
289
|
+
return $body;
|
|
290
|
+
};
|
|
291
|
+
const options = service.options;
|
|
292
|
+
if (!options.indexName)
|
|
293
|
+
throw new Error('.indexName is required');
|
|
294
|
+
this.service = service;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* get options
|
|
298
|
+
*/
|
|
299
|
+
get options() {
|
|
300
|
+
return this.service.options;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* query all by id.
|
|
304
|
+
*
|
|
305
|
+
* @param id
|
|
306
|
+
* @param limit
|
|
307
|
+
* @param isDesc
|
|
308
|
+
*/
|
|
309
|
+
queryAll(id, limit, isDesc) {
|
|
310
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
311
|
+
const { idName } = this.options;
|
|
312
|
+
const param = {
|
|
313
|
+
[idName]: id,
|
|
314
|
+
};
|
|
315
|
+
if (limit !== undefined)
|
|
316
|
+
param['$limit'] = limit;
|
|
317
|
+
if (isDesc !== undefined)
|
|
318
|
+
param['$O'] = (isDesc ? '!' : '') + id;
|
|
319
|
+
return this.searchSimple(param);
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* search in simple mode
|
|
324
|
+
* - 기본적으로 'mini-language'를 그대로 지원하도록한다.
|
|
325
|
+
* - 입력의 파라마터의 키값은 테스트할 필드들이다.
|
|
326
|
+
* {"stock":">1"} => query_string : "stock:>1"
|
|
327
|
+
*
|
|
328
|
+
* - 파라미터 예약:
|
|
329
|
+
* $query : ES _search 용 쿼리를 그대로 이용.
|
|
330
|
+
* $exist : 'a,!b,c' => a AND NOT b AND c 를 _exists_ 항목으로 풀어씀.
|
|
331
|
+
* $source : _source 항목에 포함될 내용. (undefined => _source:false)
|
|
332
|
+
* $limit : same as "size"
|
|
333
|
+
* $page : same as "from" / "size" ($limit 를 ipp 으로 함축하여 이용).
|
|
334
|
+
*
|
|
335
|
+
*
|
|
336
|
+
*
|
|
337
|
+
* [Mini-Language]
|
|
338
|
+
* ```
|
|
339
|
+
* # find title field which contains quick or brown.
|
|
340
|
+
* title:(quick OR brown)
|
|
341
|
+
*
|
|
342
|
+
* # not-null value.
|
|
343
|
+
* _exists_:title
|
|
344
|
+
*
|
|
345
|
+
* # regular exp.
|
|
346
|
+
* name:/joh?n(ath[oa]n)/
|
|
347
|
+
* ```
|
|
348
|
+
*
|
|
349
|
+
*
|
|
350
|
+
* 참고: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax
|
|
351
|
+
* 참고: http://okfnlabs.org/blog/2013/07/01/elasticsearch-query-tutorial.html
|
|
352
|
+
*
|
|
353
|
+
* @param param search param
|
|
354
|
+
*/
|
|
355
|
+
searchSimple(param) {
|
|
356
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
357
|
+
if (!param)
|
|
358
|
+
throw new Error('@param (SimpleSearchParam) is required');
|
|
359
|
+
const { indexName } = this.options;
|
|
360
|
+
(0, engine_1._log)(NS, `- searchSimple(${indexName})....`);
|
|
361
|
+
(0, engine_1._log)(NS, `> param =`, engine_1.$U.json(param));
|
|
362
|
+
//! build query body.
|
|
363
|
+
const body = this.buildQueryBody(param);
|
|
364
|
+
//! search via client
|
|
365
|
+
const res = yield this.search(body);
|
|
366
|
+
//! convert to query-result.
|
|
367
|
+
return this.asQueryResult(body, res);
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* search with raw query language.
|
|
372
|
+
*
|
|
373
|
+
* @param body SearchBody.
|
|
374
|
+
* @returns results.
|
|
375
|
+
*/
|
|
376
|
+
search(body, searchType) {
|
|
377
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
378
|
+
if (!body)
|
|
379
|
+
throw new Error('@body (SearchBody) is required');
|
|
380
|
+
return this.service.searchRaw(body, searchType);
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* convert result as `QueryResult`
|
|
385
|
+
* @param body the query body requested
|
|
386
|
+
* @param res the result
|
|
387
|
+
* @returns QueryResult
|
|
388
|
+
*/
|
|
389
|
+
asQueryResult(body, res) {
|
|
390
|
+
var _a, _b, _c;
|
|
391
|
+
const size = engine_1.$U.N(body === null || body === void 0 ? void 0 : body.size, 10);
|
|
392
|
+
//! extract for result.
|
|
393
|
+
const hits = res === null || res === void 0 ? void 0 : res.hits;
|
|
394
|
+
if (typeof hits !== 'object')
|
|
395
|
+
throw new Error(`.hits (object) is required - hists:${engine_1.$U.json(hits)}`);
|
|
396
|
+
const total = engine_1.$U.N(typeof ((_a = hits.total) === null || _a === void 0 ? void 0 : _a.value) === 'number' ? (_b = hits.total) === null || _b === void 0 ? void 0 : _b.value : hits.total, 0); // since v7.x
|
|
397
|
+
const last = (hits === null || hits === void 0 ? void 0 : hits.hits.length) === size ? (_c = hits.hits[size - 1]) === null || _c === void 0 ? void 0 : _c.sort : undefined;
|
|
398
|
+
const list = ((hits && hits.hits) || []).map((N) => {
|
|
399
|
+
const id = N && N._id; // id of elastic-search
|
|
400
|
+
const score = N && N._score; // search score.
|
|
401
|
+
const source = N && N._source; // origin data
|
|
402
|
+
//! save as internal
|
|
403
|
+
source._id = source._id || id; // attach to internal-id
|
|
404
|
+
source._score = score;
|
|
405
|
+
// delete internal autocomplete data
|
|
406
|
+
delete source[elastic6_service_1.Elastic6Service.DECOMPOSED_FIELD];
|
|
407
|
+
delete source[elastic6_service_1.Elastic6Service.QWERTY_FIELD];
|
|
408
|
+
return source;
|
|
409
|
+
});
|
|
410
|
+
const result = { list, total, last };
|
|
411
|
+
if (res === null || res === void 0 ? void 0 : res.aggregations) {
|
|
412
|
+
const $aggregations = res.aggregations || {};
|
|
413
|
+
result.aggregations = Object.keys($aggregations).reduce((aggrs, field) => {
|
|
414
|
+
const { doc_count_error_upper_bound: docCountError = 0, sum_other_doc_count: docSkippedCount = 0, buckets, } = res.aggregations[field];
|
|
415
|
+
if (docCountError > 0)
|
|
416
|
+
(0, engine_1._err)(NS, `> [WARN] aggregation: counts for each term are not accurate.`);
|
|
417
|
+
if (docSkippedCount > 0)
|
|
418
|
+
(0, engine_1._err)(NS, '> [WARN] aggregation: too many unique terms in the result. some terms are skipped.');
|
|
419
|
+
if (Array.isArray(buckets)) {
|
|
420
|
+
aggrs[field] = buckets.map((bucket) => {
|
|
421
|
+
return { key: bucket.key, count: bucket.doc_count };
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
return aggrs;
|
|
425
|
+
}, {});
|
|
426
|
+
}
|
|
427
|
+
return result;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* convert `AutocompleteSearchParam` to `SearchBody`
|
|
431
|
+
* @param param AutocompleteSearchParam
|
|
432
|
+
* @returns SearchBody
|
|
433
|
+
*/
|
|
434
|
+
asSearchBody(param) {
|
|
435
|
+
const { autocompleteFields } = this.options;
|
|
436
|
+
// validate parameters
|
|
437
|
+
if (!param)
|
|
438
|
+
throw new Error('@param (AutocompleteSearchParam) is required');
|
|
439
|
+
if (!param.$query || !Object.keys(param.$query).length)
|
|
440
|
+
throw new Error('.query is required');
|
|
441
|
+
if (Object.keys(param.$query).length > 1)
|
|
442
|
+
throw new Error('.query accepts only one property');
|
|
443
|
+
const [field, query] = Object.entries(param.$query)[0];
|
|
444
|
+
if (!field || !query)
|
|
445
|
+
throw new Error(`.query is invalid`);
|
|
446
|
+
if (!autocompleteFields.includes(field))
|
|
447
|
+
throw new Error(`.query has no autocomplete field`);
|
|
448
|
+
// build query body
|
|
449
|
+
const decomposedField = `${elastic6_service_1.Elastic6Service.DECOMPOSED_FIELD}.${field}`;
|
|
450
|
+
const qwertyField = `${elastic6_service_1.Elastic6Service.QWERTY_FIELD}.${field}`;
|
|
451
|
+
const body = {
|
|
452
|
+
query: {
|
|
453
|
+
bool: {
|
|
454
|
+
should: [
|
|
455
|
+
{ match: { [decomposedField]: hangul_service_1.default.asJamoSequence(query) } },
|
|
456
|
+
{ match: { [qwertyField]: query } },
|
|
457
|
+
],
|
|
458
|
+
minimum_should_match: 1,
|
|
459
|
+
},
|
|
460
|
+
},
|
|
461
|
+
};
|
|
462
|
+
if (param.$filter) {
|
|
463
|
+
body.query.bool.filter = Object.entries(param.$filter).map(([field, filter]) => {
|
|
464
|
+
return { term: { [field]: filter } };
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
body.size = engine_1.$U.N(param.$limit, 10);
|
|
468
|
+
body.from = engine_1.$U.N(param.$page, 0) * body.size;
|
|
469
|
+
return { field, query, body };
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* search item in Search-as-You-Type way
|
|
473
|
+
* @param param AutocompleteSearchParam
|
|
474
|
+
*/
|
|
475
|
+
searchAutocomplete(param) {
|
|
476
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
477
|
+
const { field, query, body } = this.asSearchBody(param);
|
|
478
|
+
const res = yield this.service.searchRaw(body);
|
|
479
|
+
const result = this.asQueryResult(body, res);
|
|
480
|
+
// highlighting result manually
|
|
481
|
+
let list = result.list;
|
|
482
|
+
if (param.$highlight) {
|
|
483
|
+
// prepare tag name to wrap highlighted text
|
|
484
|
+
const tagName = typeof param.$highlight == 'string' ? param.$highlight : 'em';
|
|
485
|
+
// create a regular expression which has optional whitespaces between each character
|
|
486
|
+
// e.g. 'COVID-19' => /C *O *V *I *D *- *1 *9/i
|
|
487
|
+
const regexp = new RegExp([...query.replace(/\s/g, '')].join(' *'), 'i');
|
|
488
|
+
// try to match regular expression with items found
|
|
489
|
+
list = result.list.map((item) => {
|
|
490
|
+
const target = `${item[field] || ''}`;
|
|
491
|
+
const match = target.match(regexp);
|
|
492
|
+
if (match) {
|
|
493
|
+
item._highlight =
|
|
494
|
+
target.slice(0, match.index) +
|
|
495
|
+
`<${tagName}>${match[0]}</${tagName}>` +
|
|
496
|
+
target.slice(match.index + match[0].length);
|
|
497
|
+
}
|
|
498
|
+
else {
|
|
499
|
+
item._highlight = target;
|
|
500
|
+
}
|
|
501
|
+
return item;
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
//! finally, override list.
|
|
505
|
+
return Object.assign(Object.assign({}, result), { list });
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
exports.Elastic6QueryService = Elastic6QueryService;
|
|
510
|
+
//# sourceMappingURL=elastic6-query-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elastic6-query-service.js","sourceRoot":"","sources":["../../../src/cores/elastic/elastic6-query-service.ts"],"names":[],"mappings":"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"}
|