@livequery/mongoose 2.0.21 → 2.0.23
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/build/src/MongoQuery.js +76 -60
- package/package.json +1 -1
package/build/src/MongoQuery.js
CHANGED
|
@@ -92,57 +92,75 @@ export class MongoQuery {
|
|
|
92
92
|
return stack.pop();
|
|
93
93
|
}
|
|
94
94
|
static #parse_summary(req) {
|
|
95
|
-
const
|
|
95
|
+
const parsed = Object
|
|
96
96
|
.entries(req.options)
|
|
97
|
-
.map(([
|
|
98
|
-
if (!
|
|
97
|
+
.map(([key, v], index) => {
|
|
98
|
+
if (!key.startsWith('::'))
|
|
99
99
|
return [];
|
|
100
|
-
const
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
100
|
+
const exprs = `${v}`.split('|').filter(Boolean);
|
|
101
|
+
const fns = exprs.map(l => {
|
|
102
|
+
const exp = l.split('(')[0];
|
|
103
|
+
if (!['sum', 'avg', 'max', 'min', 'count', 'distinct'].includes(exp))
|
|
104
|
+
return [];
|
|
105
|
+
if (exp == 'count' || exp == 'distinct')
|
|
106
|
+
return [{ key: exp, query: { $sum: 1 } }];
|
|
107
|
+
const infix = l.split('(')?.[1]?.split(')')?.[0];
|
|
108
|
+
if (!infix)
|
|
109
|
+
return [];
|
|
110
|
+
const key = `${exp}_${infix}`;
|
|
111
|
+
const query = this.#postfix_to_mongodb(this.#infix_to_postfix(infix));
|
|
112
|
+
return [{ key, query: { [`$${exp}`]: query } }];
|
|
113
|
+
}).flat(2);
|
|
114
|
+
const groups = exprs.filter(g => g.match(/^[a-zA-Z_]+$/));
|
|
115
|
+
const $match = exprs.map(exp => {
|
|
116
|
+
for (const { c, f } of [
|
|
117
|
+
{ c: '==', f: 'eq' },
|
|
118
|
+
{ c: '<>', f: 'ne' },
|
|
119
|
+
{ c: '>=', f: 'gte' },
|
|
120
|
+
{ c: '<=', f: 'lte' },
|
|
121
|
+
{ c: '>', f: 'gt' },
|
|
122
|
+
{ c: '<', f: 'lt' },
|
|
123
|
+
{ c: '=', f: 'eq' },
|
|
124
|
+
]) {
|
|
125
|
+
if (exp.includes(c)) {
|
|
126
|
+
const [a, b] = exp.split(c);
|
|
127
|
+
return { [a]: { [f]: isNaN(Number(b)) ? (c == '==' ? (b == 'true') : b) : Number(b) } };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}).filter(Boolean);
|
|
131
|
+
const is_distinc_count = `${v}`.includes('distinc');
|
|
132
|
+
const simple = is_distinc_count ? key : (exprs.length == 1 ? fns[0].key : false);
|
|
133
|
+
const pipelines = [
|
|
134
|
+
...$match.length > 0 ? [{ $match }] : [],
|
|
135
|
+
{
|
|
136
|
+
$group: {
|
|
137
|
+
_id: groups.length == 0 ? null : groups.reduce((p, by) => {
|
|
138
|
+
return {
|
|
139
|
+
...p,
|
|
140
|
+
[by]: `$${by}`
|
|
141
|
+
};
|
|
142
|
+
}, {}),
|
|
143
|
+
...fns.reduce((p, { query, key }) => ({
|
|
122
144
|
...p,
|
|
123
|
-
[
|
|
124
|
-
}
|
|
125
|
-
}
|
|
145
|
+
[key]: query
|
|
146
|
+
}), {})
|
|
147
|
+
}
|
|
126
148
|
},
|
|
127
|
-
...
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
return p;
|
|
133
|
-
}, new Map);
|
|
134
|
-
const pipelines = [...expresisons].reduce((p, [group_by, $group]) => {
|
|
135
|
-
return {
|
|
136
|
-
...p,
|
|
137
|
-
[group_by]: [
|
|
138
|
-
{ $group },
|
|
149
|
+
...is_distinc_count ? [
|
|
150
|
+
{
|
|
151
|
+
$count: key
|
|
152
|
+
}
|
|
153
|
+
] : [
|
|
139
154
|
{
|
|
140
155
|
$project: {
|
|
141
|
-
...
|
|
156
|
+
...groups.reduce((p, c) => ({
|
|
142
157
|
...p,
|
|
143
158
|
[c]: `$_id.${c}`
|
|
144
159
|
}), {}),
|
|
145
|
-
...
|
|
160
|
+
...fns.reduce((p, { key }) => ({
|
|
161
|
+
...p,
|
|
162
|
+
[key]: 1
|
|
163
|
+
}), {}),
|
|
146
164
|
_id: 0
|
|
147
165
|
}
|
|
148
166
|
},
|
|
@@ -150,20 +168,23 @@ export class MongoQuery {
|
|
|
150
168
|
$limit: 50
|
|
151
169
|
}
|
|
152
170
|
]
|
|
171
|
+
];
|
|
172
|
+
return [{ key, pipelines, simple }];
|
|
173
|
+
})
|
|
174
|
+
.flat(1);
|
|
175
|
+
const pipelines = parsed.reduce((p, { key, pipelines }) => ({
|
|
176
|
+
...p,
|
|
177
|
+
[key]: pipelines
|
|
178
|
+
}), {});
|
|
179
|
+
const summary = parsed.length == 0 ? undefined : parsed.reduce((p, { key, simple }) => {
|
|
180
|
+
return {
|
|
181
|
+
...p,
|
|
182
|
+
[key]: simple ? { $arrayElemAt: [`$${key}.${simple}`, 0] } : `$${key}`
|
|
153
183
|
};
|
|
154
184
|
}, {});
|
|
155
|
-
const summary = expresisons.size == 0 ? {} : {
|
|
156
|
-
summary: [...expresisons].reduce((p, [group_by, $group]) => {
|
|
157
|
-
return {
|
|
158
|
-
...p,
|
|
159
|
-
[group_by]: `$${group_by}`
|
|
160
|
-
};
|
|
161
|
-
}, {})
|
|
162
|
-
};
|
|
163
185
|
return {
|
|
164
186
|
pipelines,
|
|
165
|
-
summary
|
|
166
|
-
mappers
|
|
187
|
+
summary
|
|
167
188
|
};
|
|
168
189
|
}
|
|
169
190
|
static #parse_conditions(filters) {
|
|
@@ -294,7 +315,7 @@ export class MongoQuery {
|
|
|
294
315
|
];
|
|
295
316
|
}
|
|
296
317
|
static #build_cursor_paging($sort, req) {
|
|
297
|
-
const { pipelines, summary
|
|
318
|
+
const { pipelines, summary } = this.#parse_summary(req);
|
|
298
319
|
const limit = this.#get_limit(req);
|
|
299
320
|
return [
|
|
300
321
|
{
|
|
@@ -306,7 +327,7 @@ export class MongoQuery {
|
|
|
306
327
|
},
|
|
307
328
|
{
|
|
308
329
|
$project: {
|
|
309
|
-
|
|
330
|
+
summary,
|
|
310
331
|
prev: {
|
|
311
332
|
$ifNull: [
|
|
312
333
|
{ $arrayElemAt: ["$prev", 0] },
|
|
@@ -323,12 +344,7 @@ export class MongoQuery {
|
|
|
323
344
|
},
|
|
324
345
|
{
|
|
325
346
|
$project: {
|
|
326
|
-
summary:
|
|
327
|
-
return {
|
|
328
|
-
...p,
|
|
329
|
-
[c.name]: { $arrayElemAt: [`$summary.${c.group_id}.${c.id}`, 0] }
|
|
330
|
-
};
|
|
331
|
-
}, {}),
|
|
347
|
+
summary: 1,
|
|
332
348
|
items: {
|
|
333
349
|
$concatArrays: ["$prev.items", "$next.items"]
|
|
334
350
|
},
|
package/package.json
CHANGED