@builder6/query-mongodb 0.6.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/LICENSE +201 -0
- package/README.md +37 -0
- package/dist/index.js +272 -0
- package/dist/index.test.js +1941 -0
- package/dist/options.js +420 -0
- package/dist/options.test.js +960 -0
- package/dist/pipelines.js +751 -0
- package/dist/pipelines.test.js +782 -0
- package/dist/utils.js +45 -0
- package/dist/utils.test.js +36 -0
- package/index.js +1 -0
- package/options.js +1 -0
- package/package.json +60 -0
- package/src/index.js +497 -0
- package/src/index.test.js +2333 -0
- package/src/options.js +573 -0
- package/src/options.test.js +1112 -0
- package/src/pipelines.js +760 -0
- package/src/pipelines.test.js +1300 -0
- package/src/utils.js +33 -0
- package/src/utils.test.js +40 -0
|
@@ -0,0 +1,751 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
|
4
|
+
|
|
5
|
+
var _marked = regeneratorRuntime.mark(_fixAndChainWithIncompleteAnds);
|
|
6
|
+
|
|
7
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
8
|
+
|
|
9
|
+
var _require = require('mongodb'),
|
|
10
|
+
ObjectId = _require.ObjectId;
|
|
11
|
+
|
|
12
|
+
var createGroupFieldName = function createGroupFieldName(groupIndex) {
|
|
13
|
+
return '___group_key_' + groupIndex;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
var divInt = function divInt(dividend, divisor) {
|
|
17
|
+
return {
|
|
18
|
+
$divide: [subtractMod(dividend, divisor), divisor]
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
var subtractMod = function subtractMod(a, b) {
|
|
23
|
+
return {
|
|
24
|
+
$subtract: [a, {
|
|
25
|
+
$mod: [a, b]
|
|
26
|
+
}]
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
var createGroupKeyPipeline = function createGroupKeyPipeline(selector, groupInterval, groupIndex, contextOptions) {
|
|
31
|
+
var timezoneOffset = contextOptions.timezoneOffset;
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
var wrapGroupKey = function wrapGroupKey(keyExpr) {
|
|
35
|
+
return {
|
|
36
|
+
$addFields: _defineProperty({}, createGroupFieldName(groupIndex), keyExpr)
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
var prefix = function prefix(s) {
|
|
41
|
+
return '$' + s;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
var pipe = function pipe() {
|
|
45
|
+
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
|
|
46
|
+
args[_key] = arguments[_key];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
var result = Array.from(args);
|
|
50
|
+
result.groupIndex = groupIndex;
|
|
51
|
+
return result;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
if (groupInterval) {
|
|
55
|
+
var numericInterval = parseInt(Number(groupInterval));
|
|
56
|
+
if (numericInterval) {
|
|
57
|
+
return pipe(wrapGroupKey(subtractMod(prefix(selector), numericInterval)));
|
|
58
|
+
} else {
|
|
59
|
+
var tafield = {
|
|
60
|
+
$subtract: [prefix(selector), timezoneOffset * 60 * 1000]
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
switch (groupInterval) {
|
|
64
|
+
case 'year':
|
|
65
|
+
return pipe(wrapGroupKey({
|
|
66
|
+
$year: tafield
|
|
67
|
+
}));
|
|
68
|
+
case 'quarter':
|
|
69
|
+
return pipe({
|
|
70
|
+
$addFields: {
|
|
71
|
+
___mp2: {
|
|
72
|
+
$add: [{
|
|
73
|
+
$month: tafield
|
|
74
|
+
}, 2]
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}, wrapGroupKey(divInt('$___mp2', 3)));
|
|
78
|
+
case 'month':
|
|
79
|
+
return pipe(wrapGroupKey({
|
|
80
|
+
$month: tafield
|
|
81
|
+
}));
|
|
82
|
+
case 'day':
|
|
83
|
+
return pipe(wrapGroupKey({
|
|
84
|
+
$dayOfMonth: tafield
|
|
85
|
+
}));
|
|
86
|
+
case 'dayOfWeek':
|
|
87
|
+
return pipe(wrapGroupKey({
|
|
88
|
+
$subtract: [{
|
|
89
|
+
$dayOfWeek: tafield }, 1]
|
|
90
|
+
}));
|
|
91
|
+
case 'hour':
|
|
92
|
+
return pipe(wrapGroupKey({
|
|
93
|
+
$hour: tafield
|
|
94
|
+
}));
|
|
95
|
+
case 'minute':
|
|
96
|
+
return pipe(wrapGroupKey({
|
|
97
|
+
$minute: tafield
|
|
98
|
+
}));
|
|
99
|
+
case 'second':
|
|
100
|
+
return pipe(wrapGroupKey({
|
|
101
|
+
$second: tafield
|
|
102
|
+
}));
|
|
103
|
+
default:
|
|
104
|
+
return pipe(wrapGroupKey(prefix(selector)));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
} else {
|
|
108
|
+
return pipe(wrapGroupKey(prefix(selector)));
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
var createGroupStagePipeline = function createGroupStagePipeline(includeDataItems, countingSeparately, itemProjection, groupKeyPipeline) {
|
|
113
|
+
var result = {
|
|
114
|
+
$group: {
|
|
115
|
+
_id: '$' + createGroupFieldName(groupKeyPipeline.groupIndex)
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
if (!countingSeparately) {
|
|
119
|
+
result.$group.count = {
|
|
120
|
+
$sum: 1
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
if (includeDataItems) {
|
|
124
|
+
result.$group.items = {
|
|
125
|
+
$push: itemProjection
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return groupKeyPipeline.concat([result]);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
var createGroupingPipeline = function createGroupingPipeline(desc, includeDataItems, countingSeparately, groupKeyPipeline) {
|
|
133
|
+
var itemProjection = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : '$$CURRENT';
|
|
134
|
+
|
|
135
|
+
var projectStage = {
|
|
136
|
+
$project: {
|
|
137
|
+
_id: 0,
|
|
138
|
+
key: '$_id'
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
var sortStage = {
|
|
142
|
+
$sort: {
|
|
143
|
+
key: desc ? -1 : 1
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
var pipeline = createGroupStagePipeline(includeDataItems, countingSeparately, itemProjection, groupKeyPipeline).concat([projectStage, sortStage]);
|
|
148
|
+
|
|
149
|
+
if (!countingSeparately) {
|
|
150
|
+
projectStage.$project.count = 1;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (includeDataItems) {
|
|
154
|
+
projectStage.$project.items = 1;
|
|
155
|
+
} else {
|
|
156
|
+
pipeline.push({
|
|
157
|
+
$addFields: {
|
|
158
|
+
items: null }
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return pipeline;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
var createSkipTakePipeline = function createSkipTakePipeline(skip, take) {
|
|
166
|
+
var pipeline = [];
|
|
167
|
+
|
|
168
|
+
if (skip) pipeline.push({
|
|
169
|
+
$skip: skip
|
|
170
|
+
});
|
|
171
|
+
if (take) pipeline.push({
|
|
172
|
+
$limit: take
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
return pipeline;
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
var createCountPipeline = function createCountPipeline() {
|
|
179
|
+
return [{
|
|
180
|
+
$count: 'count'
|
|
181
|
+
}];
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
var createMatchPipeline = function createMatchPipeline(selector, value) {
|
|
185
|
+
return [{ $match: _defineProperty({}, selector, value) }];
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
var construct = function construct(fieldName, operator, compValue) {
|
|
189
|
+
return _defineProperty({}, fieldName, _defineProperty({}, operator, compValue));
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
var constructRegex = function constructRegex(fieldName, regex, caseInsensitive) {
|
|
193
|
+
return _defineProperty({}, fieldName, { $regex: regex, $options: caseInsensitive ? 'i' : '' });
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
var isCorrectFilterOperatorStructure = function isCorrectFilterOperatorStructure(element, operator) {
|
|
197
|
+
return element.reduce(function (r, v) {
|
|
198
|
+
if (r.previous) return { ok: r.ok, previous: false };else return {
|
|
199
|
+
ok: r.ok && typeof v === 'string' && v.toLowerCase() === operator,
|
|
200
|
+
previous: true
|
|
201
|
+
};
|
|
202
|
+
}, { ok: true, previous: true }).ok;
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
var isAndChainWithIncompleteAnds = function isAndChainWithIncompleteAnds(element) {
|
|
206
|
+
if (!Array.isArray(element)) return false;
|
|
207
|
+
if (element.length < 2) return false;
|
|
208
|
+
if (!Array.isArray(element[0])) return false;
|
|
209
|
+
|
|
210
|
+
if (isCorrectFilterOperatorStructure(element, 'and')) return false;
|
|
211
|
+
return element.reduce(function (r, v) {
|
|
212
|
+
return r && (typeof v === 'string' && v.toLowerCase() === 'and' || Array.isArray(v));
|
|
213
|
+
}, true);
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
function _fixAndChainWithIncompleteAnds(chain) {
|
|
217
|
+
var firstDone, expectAnd, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, item;
|
|
218
|
+
|
|
219
|
+
return regeneratorRuntime.wrap(function _fixAndChainWithIncompleteAnds$(_context) {
|
|
220
|
+
while (1) {
|
|
221
|
+
switch (_context.prev = _context.next) {
|
|
222
|
+
case 0:
|
|
223
|
+
firstDone = false;
|
|
224
|
+
expectAnd = true;
|
|
225
|
+
_iteratorNormalCompletion = true;
|
|
226
|
+
_didIteratorError = false;
|
|
227
|
+
_iteratorError = undefined;
|
|
228
|
+
_context.prev = 5;
|
|
229
|
+
_iterator = chain[Symbol.iterator]();
|
|
230
|
+
|
|
231
|
+
case 7:
|
|
232
|
+
if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
|
|
233
|
+
_context.next = 35;
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
item = _step.value;
|
|
238
|
+
|
|
239
|
+
if (firstDone) {
|
|
240
|
+
_context.next = 15;
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
_context.next = 12;
|
|
245
|
+
return item;
|
|
246
|
+
|
|
247
|
+
case 12:
|
|
248
|
+
firstDone = true;
|
|
249
|
+
_context.next = 32;
|
|
250
|
+
break;
|
|
251
|
+
|
|
252
|
+
case 15:
|
|
253
|
+
if (!expectAnd) {
|
|
254
|
+
_context.next = 28;
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (!(typeof item === 'string')) {
|
|
259
|
+
_context.next = 22;
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
_context.next = 19;
|
|
264
|
+
return 'and';
|
|
265
|
+
|
|
266
|
+
case 19:
|
|
267
|
+
expectAnd = false;
|
|
268
|
+
_context.next = 26;
|
|
269
|
+
break;
|
|
270
|
+
|
|
271
|
+
case 22:
|
|
272
|
+
_context.next = 24;
|
|
273
|
+
return 'and';
|
|
274
|
+
|
|
275
|
+
case 24:
|
|
276
|
+
_context.next = 26;
|
|
277
|
+
return item;
|
|
278
|
+
|
|
279
|
+
case 26:
|
|
280
|
+
_context.next = 32;
|
|
281
|
+
break;
|
|
282
|
+
|
|
283
|
+
case 28:
|
|
284
|
+
if (!(typeof item !== 'string')) {
|
|
285
|
+
_context.next = 32;
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
_context.next = 31;
|
|
290
|
+
return item;
|
|
291
|
+
|
|
292
|
+
case 31:
|
|
293
|
+
expectAnd = true;
|
|
294
|
+
|
|
295
|
+
case 32:
|
|
296
|
+
_iteratorNormalCompletion = true;
|
|
297
|
+
_context.next = 7;
|
|
298
|
+
break;
|
|
299
|
+
|
|
300
|
+
case 35:
|
|
301
|
+
_context.next = 41;
|
|
302
|
+
break;
|
|
303
|
+
|
|
304
|
+
case 37:
|
|
305
|
+
_context.prev = 37;
|
|
306
|
+
_context.t0 = _context['catch'](5);
|
|
307
|
+
_didIteratorError = true;
|
|
308
|
+
_iteratorError = _context.t0;
|
|
309
|
+
|
|
310
|
+
case 41:
|
|
311
|
+
_context.prev = 41;
|
|
312
|
+
_context.prev = 42;
|
|
313
|
+
|
|
314
|
+
if (!_iteratorNormalCompletion && _iterator.return) {
|
|
315
|
+
_iterator.return();
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
case 44:
|
|
319
|
+
_context.prev = 44;
|
|
320
|
+
|
|
321
|
+
if (!_didIteratorError) {
|
|
322
|
+
_context.next = 47;
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
throw _iteratorError;
|
|
327
|
+
|
|
328
|
+
case 47:
|
|
329
|
+
return _context.finish(44);
|
|
330
|
+
|
|
331
|
+
case 48:
|
|
332
|
+
return _context.finish(41);
|
|
333
|
+
|
|
334
|
+
case 49:
|
|
335
|
+
case 'end':
|
|
336
|
+
return _context.stop();
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}, _marked, this, [[5, 37, 41, 49], [42,, 44, 48]]);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
var fixAndChainWithIncompleteAnds = function fixAndChainWithIncompleteAnds(element) {
|
|
343
|
+
return Array.from(_fixAndChainWithIncompleteAnds(element));
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
var parseFilter = function parseFilter(element) {
|
|
347
|
+
var contextOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
348
|
+
var caseInsensitiveRegex = contextOptions.caseInsensitiveRegex;
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
var rval = function rval(match, fieldList) {
|
|
352
|
+
return { match: match, fieldList: fieldList };
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
if (typeof element === 'string') {
|
|
356
|
+
var nf = checkNestedField(element);
|
|
357
|
+
var fieldName = nf ? nf.filterFieldName : element;
|
|
358
|
+
return rval(construct(fieldName, '$eq', true), [element]);
|
|
359
|
+
} else if (Array.isArray(element)) {
|
|
360
|
+
if (element.length === 1 && Array.isArray(element[0])) {
|
|
361
|
+
return parseFilter(element[0], contextOptions);
|
|
362
|
+
} else if (element.length === 2) {
|
|
363
|
+
if (element[0] === '!') {
|
|
364
|
+
var _parseFilter = parseFilter(element[1], contextOptions),
|
|
365
|
+
match = _parseFilter.match,
|
|
366
|
+
fieldList = _parseFilter.fieldList;
|
|
367
|
+
|
|
368
|
+
if (match) return rval({
|
|
369
|
+
$nor: [match]
|
|
370
|
+
}, fieldList);else return null;
|
|
371
|
+
} else if (isAndChainWithIncompleteAnds(element)) return parseFilter(fixAndChainWithIncompleteAnds(element), contextOptions);else return null;
|
|
372
|
+
} else {
|
|
373
|
+
if (isAndChainWithIncompleteAnds(element)) return parseFilter(fixAndChainWithIncompleteAnds(element), contextOptions);else if (element.length % 2 === 1) {
|
|
374
|
+
var operator = String(element[1]).toLowerCase();
|
|
375
|
+
|
|
376
|
+
if (['and', 'or'].includes(operator)) {
|
|
377
|
+
if (isCorrectFilterOperatorStructure(element, operator)) {
|
|
378
|
+
var result = element.reduce(function (r, v) {
|
|
379
|
+
if (r.previous) return _extends({}, r, { previous: false });else {
|
|
380
|
+
var nestedResult = parseFilter(v, contextOptions);
|
|
381
|
+
var nestedFilter = nestedResult && nestedResult.match;
|
|
382
|
+
var _fieldList = nestedResult ? nestedResult.fieldList : [];
|
|
383
|
+
if (nestedFilter) r.list.push(nestedFilter);
|
|
384
|
+
return {
|
|
385
|
+
list: r.list,
|
|
386
|
+
fieldList: r.fieldList.concat(_fieldList),
|
|
387
|
+
previous: true
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
}, { list: [], fieldList: [], previous: false });
|
|
391
|
+
|
|
392
|
+
return rval(_defineProperty({}, '$' + operator, result.list), result.fieldList);
|
|
393
|
+
} else return null;
|
|
394
|
+
} else {
|
|
395
|
+
if (element.length === 3) {
|
|
396
|
+
var _nf = checkNestedField(element[0]);
|
|
397
|
+
var _fieldName2 = _nf ? _nf.filterFieldName : element[0];
|
|
398
|
+
|
|
399
|
+
switch (operator) {
|
|
400
|
+
case '=':
|
|
401
|
+
return rval(construct(_fieldName2, '$eq', element[2]), [element[0]]);
|
|
402
|
+
case '<>':
|
|
403
|
+
return rval(construct(_fieldName2, '$ne', element[2]), [element[0]]);
|
|
404
|
+
case '>':
|
|
405
|
+
return rval(construct(_fieldName2, '$gt', element[2]), [element[0]]);
|
|
406
|
+
case '>=':
|
|
407
|
+
return rval(construct(_fieldName2, '$gte', element[2]), [element[0]]);
|
|
408
|
+
case '<':
|
|
409
|
+
return rval(construct(_fieldName2, '$lt', element[2]), [element[0]]);
|
|
410
|
+
case '<=':
|
|
411
|
+
return rval(construct(_fieldName2, '$lte', element[2]), [element[0]]);
|
|
412
|
+
case 'startswith':
|
|
413
|
+
return rval(constructRegex(_fieldName2, '^' + element[2], caseInsensitiveRegex), [element[0]]);
|
|
414
|
+
case 'endswith':
|
|
415
|
+
return rval(constructRegex(_fieldName2, element[2] + '$', caseInsensitiveRegex), [element[0]]);
|
|
416
|
+
case 'contains':
|
|
417
|
+
return rval(constructRegex(_fieldName2, element[2], caseInsensitiveRegex), [element[0]]);
|
|
418
|
+
case 'notcontains':
|
|
419
|
+
return rval(constructRegex(_fieldName2, '^((?!' + element[2] + ').)*$', caseInsensitiveRegex), [element[0]]);
|
|
420
|
+
case 'equalsobjectid':
|
|
421
|
+
return rval(construct(_fieldName2, '$eq', new ObjectId(element[2])), [element[0]]);
|
|
422
|
+
default:
|
|
423
|
+
return null;
|
|
424
|
+
}
|
|
425
|
+
} else return null;
|
|
426
|
+
}
|
|
427
|
+
} else return null;
|
|
428
|
+
}
|
|
429
|
+
} else return null;
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
var createFilterPipeline = function createFilterPipeline(filter, contextOptions) {
|
|
433
|
+
var dummy = {
|
|
434
|
+
pipeline: [],
|
|
435
|
+
fieldList: []
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
if (filter) {
|
|
439
|
+
var result = parseFilter(filter, contextOptions);
|
|
440
|
+
var match = result && result.match;
|
|
441
|
+
var fieldList = result ? result.fieldList : [];
|
|
442
|
+
if (match) return {
|
|
443
|
+
pipeline: [{
|
|
444
|
+
$match: match
|
|
445
|
+
}],
|
|
446
|
+
fieldList: fieldList
|
|
447
|
+
};else return dummy;
|
|
448
|
+
} else return dummy;
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
var createSortPipeline = function createSortPipeline(sort) {
|
|
452
|
+
return sort ? [{
|
|
453
|
+
$sort: sort.reduce(function (r, v) {
|
|
454
|
+
return _extends({}, r, _defineProperty({}, v.selector, v.desc ? -1 : 1));
|
|
455
|
+
}, {})
|
|
456
|
+
}] : [];
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
var createSummaryPipeline = function createSummaryPipeline(summary) {
|
|
460
|
+
if (summary) {
|
|
461
|
+
var gc = { _id: null };
|
|
462
|
+
var _iteratorNormalCompletion2 = true;
|
|
463
|
+
var _didIteratorError2 = false;
|
|
464
|
+
var _iteratorError2 = undefined;
|
|
465
|
+
|
|
466
|
+
try {
|
|
467
|
+
for (var _iterator2 = summary[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
|
468
|
+
var s = _step2.value;
|
|
469
|
+
|
|
470
|
+
switch (s.summaryType) {
|
|
471
|
+
case 'sum':
|
|
472
|
+
case 'avg':
|
|
473
|
+
case 'min':
|
|
474
|
+
case 'max':
|
|
475
|
+
gc['___' + s.summaryType + s.selector] = _defineProperty({}, '$' + s.summaryType, '$' + s.selector);
|
|
476
|
+
break;
|
|
477
|
+
case 'count':
|
|
478
|
+
gc.___count = { $sum: 1 };
|
|
479
|
+
break;
|
|
480
|
+
default:
|
|
481
|
+
console.error('Invalid summary type \'' + s.summaryType + '\', ignoring');
|
|
482
|
+
break;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
} catch (err) {
|
|
486
|
+
_didIteratorError2 = true;
|
|
487
|
+
_iteratorError2 = err;
|
|
488
|
+
} finally {
|
|
489
|
+
try {
|
|
490
|
+
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
|
491
|
+
_iterator2.return();
|
|
492
|
+
}
|
|
493
|
+
} finally {
|
|
494
|
+
if (_didIteratorError2) {
|
|
495
|
+
throw _iteratorError2;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
return [{
|
|
501
|
+
$group: gc
|
|
502
|
+
}];
|
|
503
|
+
} else return [];
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
var createSearchPipeline = function createSearchPipeline(expr, op, val, contextOptions) {
|
|
507
|
+
var dummy = {
|
|
508
|
+
pipeline: [],
|
|
509
|
+
fieldList: []
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
if (!expr || !op || !val) return dummy;
|
|
513
|
+
|
|
514
|
+
var criteria = void 0;
|
|
515
|
+
if (typeof expr === 'string') criteria = [expr, op, val];else if (expr.length > 0) {
|
|
516
|
+
criteria = [];
|
|
517
|
+
var _iteratorNormalCompletion3 = true;
|
|
518
|
+
var _didIteratorError3 = false;
|
|
519
|
+
var _iteratorError3 = undefined;
|
|
520
|
+
|
|
521
|
+
try {
|
|
522
|
+
for (var _iterator3 = expr[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
|
523
|
+
var exprItem = _step3.value;
|
|
524
|
+
|
|
525
|
+
if (criteria.length) criteria.push('or');
|
|
526
|
+
criteria.push([exprItem, op, val]);
|
|
527
|
+
}
|
|
528
|
+
} catch (err) {
|
|
529
|
+
_didIteratorError3 = true;
|
|
530
|
+
_iteratorError3 = err;
|
|
531
|
+
} finally {
|
|
532
|
+
try {
|
|
533
|
+
if (!_iteratorNormalCompletion3 && _iterator3.return) {
|
|
534
|
+
_iterator3.return();
|
|
535
|
+
}
|
|
536
|
+
} finally {
|
|
537
|
+
if (_didIteratorError3) {
|
|
538
|
+
throw _iteratorError3;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
} else return dummy;
|
|
543
|
+
|
|
544
|
+
return createFilterPipeline(criteria, contextOptions);
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
var createSelectProjectExpression = function createSelectProjectExpression(fields) {
|
|
548
|
+
var explicitId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
549
|
+
|
|
550
|
+
if (fields && fields.length > 0) {
|
|
551
|
+
var project = {};
|
|
552
|
+
if (explicitId) project._id = '$_id';
|
|
553
|
+
var _iteratorNormalCompletion4 = true;
|
|
554
|
+
var _didIteratorError4 = false;
|
|
555
|
+
var _iteratorError4 = undefined;
|
|
556
|
+
|
|
557
|
+
try {
|
|
558
|
+
for (var _iterator4 = fields[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
|
|
559
|
+
var field = _step4.value;
|
|
560
|
+
project[field] = '$' + field;
|
|
561
|
+
}
|
|
562
|
+
} catch (err) {
|
|
563
|
+
_didIteratorError4 = true;
|
|
564
|
+
_iteratorError4 = err;
|
|
565
|
+
} finally {
|
|
566
|
+
try {
|
|
567
|
+
if (!_iteratorNormalCompletion4 && _iterator4.return) {
|
|
568
|
+
_iterator4.return();
|
|
569
|
+
}
|
|
570
|
+
} finally {
|
|
571
|
+
if (_didIteratorError4) {
|
|
572
|
+
throw _iteratorError4;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
return project;
|
|
578
|
+
} else return undefined;
|
|
579
|
+
};
|
|
580
|
+
|
|
581
|
+
var createSelectPipeline = function createSelectPipeline(fields, contextOptions) {
|
|
582
|
+
if (fields && fields.length > 0) {
|
|
583
|
+
return [{
|
|
584
|
+
$project: createSelectProjectExpression(fields, contextOptions)
|
|
585
|
+
}];
|
|
586
|
+
} else return [];
|
|
587
|
+
};
|
|
588
|
+
|
|
589
|
+
var nestedFieldRegex = /^([^.]+)\.(year|quarter|month|dayofweek|day)$/i;
|
|
590
|
+
|
|
591
|
+
var checkNestedField = function checkNestedField(fieldName) {
|
|
592
|
+
var match = nestedFieldRegex.exec(fieldName);
|
|
593
|
+
if (!match) return undefined;
|
|
594
|
+
return {
|
|
595
|
+
base: match[1],
|
|
596
|
+
nested: match[2],
|
|
597
|
+
filterFieldName: '___' + match[1] + '_' + match[2]
|
|
598
|
+
};
|
|
599
|
+
};
|
|
600
|
+
|
|
601
|
+
var createAddNestedFieldsPipeline = function createAddNestedFieldsPipeline(fieldNames, contextOptions) {
|
|
602
|
+
var timezoneOffset = contextOptions.timezoneOffset;
|
|
603
|
+
|
|
604
|
+
var pr = fieldNames.reduce(function (r, v) {
|
|
605
|
+
var nf = checkNestedField(v);
|
|
606
|
+
|
|
607
|
+
if (nf) {
|
|
608
|
+
var nestedFunction = nf.nested.toLowerCase();
|
|
609
|
+
if (['year', 'quarter', 'month', 'day', 'dayofweek'].includes(nestedFunction)) {
|
|
610
|
+
var tafield = {
|
|
611
|
+
$subtract: ['$' + nf.base, timezoneOffset * 60 * 1000]
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
switch (nestedFunction) {
|
|
615
|
+
case 'year':
|
|
616
|
+
r.pipeline[1][nf.filterFieldName] = {
|
|
617
|
+
$year: tafield
|
|
618
|
+
};
|
|
619
|
+
r.nestedFields.push(nf.filterFieldName);
|
|
620
|
+
break;
|
|
621
|
+
case 'quarter':
|
|
622
|
+
{
|
|
623
|
+
var tempField = '___' + nf.base + '_mp2';
|
|
624
|
+
r.pipeline[0][tempField] = {
|
|
625
|
+
$add: [{
|
|
626
|
+
$month: tafield
|
|
627
|
+
}, 2]
|
|
628
|
+
};
|
|
629
|
+
r.nestedFields.push(tempField);
|
|
630
|
+
r.pipeline[1][nf.filterFieldName] = divInt('$' + tempField, 3);
|
|
631
|
+
r.nestedFields.push(nf.filterFieldName);
|
|
632
|
+
break;
|
|
633
|
+
}
|
|
634
|
+
case 'month':
|
|
635
|
+
r.pipeline[1][nf.filterFieldName] = {
|
|
636
|
+
$month: tafield
|
|
637
|
+
};
|
|
638
|
+
r.nestedFields.push(nf.filterFieldName);
|
|
639
|
+
break;
|
|
640
|
+
case 'day':
|
|
641
|
+
r.pipeline[1][nf.filterFieldName] = {
|
|
642
|
+
$dayOfMonth: tafield
|
|
643
|
+
};
|
|
644
|
+
r.nestedFields.push(nf.filterFieldName);
|
|
645
|
+
break;
|
|
646
|
+
case 'dayofweek':
|
|
647
|
+
r.pipeline[1][nf.filterFieldName] = {
|
|
648
|
+
$subtract: [{
|
|
649
|
+
$dayOfWeek: tafield
|
|
650
|
+
}, 1]
|
|
651
|
+
};
|
|
652
|
+
r.nestedFields.push(nf.filterFieldName);
|
|
653
|
+
break;
|
|
654
|
+
default:
|
|
655
|
+
console.error('Hit a completely impossible default case');
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
return r;
|
|
660
|
+
}, {
|
|
661
|
+
pipeline: [{}, {}],
|
|
662
|
+
nestedFields: []
|
|
663
|
+
});
|
|
664
|
+
[1, 0].forEach(function (i) {
|
|
665
|
+
if (Object.getOwnPropertyNames(pr.pipeline[i]).length === 0) {
|
|
666
|
+
pr.pipeline.splice(i, 1);
|
|
667
|
+
} else {
|
|
668
|
+
pr.pipeline[i] = {
|
|
669
|
+
$addFields: pr.pipeline[i]
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
});
|
|
673
|
+
|
|
674
|
+
return pr;
|
|
675
|
+
};
|
|
676
|
+
|
|
677
|
+
var createCompleteFilterPipeline = function createCompleteFilterPipeline(searchExpr, searchOperation, searchValue, filter, contextOptions) {
|
|
678
|
+
var searchPipeline = createSearchPipeline(searchExpr, searchOperation, searchValue, contextOptions);
|
|
679
|
+
|
|
680
|
+
var filterPipeline = createFilterPipeline(filter, contextOptions);
|
|
681
|
+
|
|
682
|
+
var addNestedFieldsPipelineDetails = createAddNestedFieldsPipeline(searchPipeline.fieldList.concat(filterPipeline.fieldList), contextOptions);
|
|
683
|
+
|
|
684
|
+
return {
|
|
685
|
+
pipeline: addNestedFieldsPipelineDetails.pipeline.concat(searchPipeline.pipeline, filterPipeline.pipeline),
|
|
686
|
+
nestedFields: addNestedFieldsPipelineDetails.nestedFields
|
|
687
|
+
};
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
var createRemoveNestedFieldsPipeline = function createRemoveNestedFieldsPipeline(nestedFields) {
|
|
691
|
+
if (nestedFields.length === 0) return [];
|
|
692
|
+
|
|
693
|
+
var pd = {};
|
|
694
|
+
var _iteratorNormalCompletion5 = true;
|
|
695
|
+
var _didIteratorError5 = false;
|
|
696
|
+
var _iteratorError5 = undefined;
|
|
697
|
+
|
|
698
|
+
try {
|
|
699
|
+
for (var _iterator5 = nestedFields[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
|
|
700
|
+
var f = _step5.value;
|
|
701
|
+
pd[f] = 0;
|
|
702
|
+
}
|
|
703
|
+
} catch (err) {
|
|
704
|
+
_didIteratorError5 = true;
|
|
705
|
+
_iteratorError5 = err;
|
|
706
|
+
} finally {
|
|
707
|
+
try {
|
|
708
|
+
if (!_iteratorNormalCompletion5 && _iterator5.return) {
|
|
709
|
+
_iterator5.return();
|
|
710
|
+
}
|
|
711
|
+
} finally {
|
|
712
|
+
if (_didIteratorError5) {
|
|
713
|
+
throw _iteratorError5;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
return [{
|
|
719
|
+
$project: pd
|
|
720
|
+
}];
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
module.exports = {
|
|
724
|
+
createGroupFieldName: createGroupFieldName,
|
|
725
|
+
createGroupKeyPipeline: createGroupKeyPipeline,
|
|
726
|
+
createGroupingPipeline: createGroupingPipeline,
|
|
727
|
+
createSkipTakePipeline: createSkipTakePipeline,
|
|
728
|
+
createCountPipeline: createCountPipeline,
|
|
729
|
+
createMatchPipeline: createMatchPipeline,
|
|
730
|
+
createSortPipeline: createSortPipeline,
|
|
731
|
+
createSummaryPipeline: createSummaryPipeline,
|
|
732
|
+
createSelectProjectExpression: createSelectProjectExpression,
|
|
733
|
+
createSelectPipeline: createSelectPipeline,
|
|
734
|
+
createCompleteFilterPipeline: createCompleteFilterPipeline,
|
|
735
|
+
createRemoveNestedFieldsPipeline: createRemoveNestedFieldsPipeline,
|
|
736
|
+
testing: {
|
|
737
|
+
divInt: divInt,
|
|
738
|
+
subtractMod: subtractMod,
|
|
739
|
+
createGroupStagePipeline: createGroupStagePipeline,
|
|
740
|
+
construct: construct,
|
|
741
|
+
constructRegex: constructRegex,
|
|
742
|
+
parseFilter: parseFilter,
|
|
743
|
+
createFilterPipeline: createFilterPipeline,
|
|
744
|
+
createSearchPipeline: createSearchPipeline,
|
|
745
|
+
checkNestedField: checkNestedField,
|
|
746
|
+
createAddNestedFieldsPipeline: createAddNestedFieldsPipeline,
|
|
747
|
+
isAndChainWithIncompleteAnds: isAndChainWithIncompleteAnds,
|
|
748
|
+
fixAndChainWithIncompleteAnds: fixAndChainWithIncompleteAnds,
|
|
749
|
+
isCorrectFilterOperatorStructure: isCorrectFilterOperatorStructure
|
|
750
|
+
}
|
|
751
|
+
};
|