@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.
@@ -92,57 +92,75 @@ export class MongoQuery {
92
92
  return stack.pop();
93
93
  }
94
94
  static #parse_summary(req) {
95
- const mappers = Object
95
+ const parsed = Object
96
96
  .entries(req.options)
97
- .map(([k, v]) => {
98
- if (!k.startsWith('::'))
97
+ .map(([key, v], index) => {
98
+ if (!key.startsWith('::'))
99
99
  return [];
100
- const [a, ...groups] = `${v}`.split('|');
101
- const [expr, infix] = a.split(')')[0].split('(');
102
- if (!['sum', 'avg', 'max', 'min', 'count'].includes(expr))
103
- return [];
104
- const query = this.#postfix_to_mongodb(this.#infix_to_postfix(infix));
105
- const group_by = groups.length == 0 ? 'NO_GROUP' : groups.join('|');
106
- return [{
107
- id: Buffer.from(k, 'utf-8').toString('hex'),
108
- group_id: Buffer.from(group_by, 'utf-8').toString('hex'),
109
- name: k.split('::')[1] || '#',
110
- expr: expr.toLowerCase(),
111
- query,
112
- groups,
113
- group_by
114
- }];
115
- })
116
- .flat(2);
117
- const expresisons = mappers.reduce((p, { expr, query, groups, group_id, id }) => {
118
- p.set(group_id, {
119
- ...p.has(group_id) ? p.get(group_id) : {
120
- _id: groups.length == 0 ? null : groups.reduce((p, by) => {
121
- return {
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
- [by]: `$${by}`
124
- };
125
- }, {}),
145
+ [key]: query
146
+ }), {})
147
+ }
126
148
  },
127
- ...expr == 'count' ? { [id]: { $sum: 1 } } : {},
128
- ...expr == 'max' ? { [id]: { $max: query } } : {},
129
- ...expr == 'min' ? { [id]: { $min: query } } : {},
130
- ...expr == 'sum' ? { [id]: { $sum: query } } : {}
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
- ...Object.keys($group._id || {}).reduce((p, c) => ({
156
+ ...groups.reduce((p, c) => ({
142
157
  ...p,
143
158
  [c]: `$_id.${c}`
144
159
  }), {}),
145
- ...Object.keys($group).reduce((p, c) => ({ ...p, [c]: 1 }), {}),
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, mappers } = this.#parse_summary(req);
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
- ...summary,
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: mappers.length == 0 ? 1 : mappers.reduce((p, c) => {
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
@@ -6,7 +6,7 @@
6
6
  "repository": {
7
7
  "url": "git@github.com:livequery/mongoose.git"
8
8
  },
9
- "version": "2.0.21",
9
+ "version": "2.0.23",
10
10
  "description": "Mongoose datasource mapping for @livequery ecosystem",
11
11
  "main": "./build/src/index.js",
12
12
  "types": "./build/src/index.d.ts",