@drax/crud-back 2.6.0 → 2.9.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.
@@ -153,6 +153,7 @@ class AbstractMongoRepository {
153
153
  }
154
154
  }
155
155
  MongooseQueryFilter.applyFilters(query, filters);
156
+ // console.log("Paginate Query", query)
156
157
  const sort = MongooseSort.applySort(orderBy, order);
157
158
  const populate = this._populateFields;
158
159
  const lean = this._lean;
@@ -218,6 +219,7 @@ class AbstractMongoRepository {
218
219
  async groupBy({ fields = [], filters = [], dateFormat = 'day' }) {
219
220
  const query = {};
220
221
  MongooseQueryFilter.applyFilters(query, filters);
222
+ // console.log("groupBy Query", query)
221
223
  // Obtener el schema para identificar campos de referencia y fechas
222
224
  const schema = this._model.schema;
223
225
  // Construir el objeto de agrupación dinámicamente
@@ -226,6 +228,13 @@ class AbstractMongoRepository {
226
228
  const finalProjectFields = { count: 1, _id: 0 };
227
229
  const refFields = new Set();
228
230
  const dateFields = new Set();
231
+ const numericFields = new Set();
232
+ const groupFields = [];
233
+ const numericInstances = new Set(['Number', 'Decimal128', 'Double', 'Int32', 'Long', 'BigInt']);
234
+ const totalGroupFields = fields.filter(field => {
235
+ const schemaPath = schema.path(field);
236
+ return !(schemaPath && numericInstances.has(schemaPath.instance));
237
+ }).length;
229
238
  // Función para obtener el formato de fecha según el nivel de granularidad
230
239
  const getDateFormat = (field, format) => {
231
240
  const formats = {
@@ -282,6 +291,13 @@ class AbstractMongoRepository {
282
291
  };
283
292
  fields.forEach(field => {
284
293
  const schemaPath = schema.path(field);
294
+ // Verificar si el campo es numérico: se agregará con $sum y no formará parte de la clave de agrupación
295
+ if (schemaPath && numericInstances.has(schemaPath.instance)) {
296
+ numericFields.add(field);
297
+ finalProjectFields[field] = 1;
298
+ return;
299
+ }
300
+ groupFields.push(field);
285
301
  // Verificar si el campo es de tipo Date
286
302
  if (schemaPath && schemaPath.instance === 'Date') {
287
303
  dateFields.add(field);
@@ -296,7 +312,7 @@ class AbstractMongoRepository {
296
312
  const refModelInstance = mongoose.model(refModel);
297
313
  const collectionName = refModelInstance.collection.name;
298
314
  // Determinar el campo local correcto según si es un solo campo o múltiples
299
- const localField = fields.length === 1 ? '_id' : `_id.${fieldName}`;
315
+ const localField = totalGroupFields === 1 ? '_id' : `_id.${fieldName}`;
300
316
  lookupStages.push({
301
317
  $lookup: {
302
318
  from: collectionName,
@@ -322,9 +338,9 @@ class AbstractMongoRepository {
322
338
  }
323
339
  });
324
340
  // Construir la proyección final para campos de fecha
325
- fields.forEach(field => {
341
+ groupFields.forEach(field => {
326
342
  if (dateFields.has(field)) {
327
- if (fields.length === 1) {
343
+ if (groupFields.length === 1) {
328
344
  finalProjectFields[field] = `$_id`;
329
345
  }
330
346
  else {
@@ -332,7 +348,7 @@ class AbstractMongoRepository {
332
348
  }
333
349
  }
334
350
  else if (!refFields.has(field)) {
335
- if (fields.length === 1) {
351
+ if (groupFields.length === 1) {
336
352
  finalProjectFields[field] = `$_id`;
337
353
  }
338
354
  else {
@@ -340,13 +356,24 @@ class AbstractMongoRepository {
340
356
  }
341
357
  }
342
358
  });
359
+ const groupStage = {
360
+ _id: null,
361
+ count: { $sum: 1 }
362
+ };
363
+ numericFields.forEach(field => {
364
+ groupStage[field] = { $sum: { $ifNull: [`$${field}`, 0] } };
365
+ });
366
+ if (groupFields.length === 1) {
367
+ const field = groupFields[0];
368
+ groupStage._id = dateFields.has(field) ? getDateFormat(field, dateFormat) : groupId[field];
369
+ }
370
+ else if (groupFields.length > 1) {
371
+ groupStage._id = groupId;
372
+ }
343
373
  const pipeline = [
344
374
  { $match: query },
345
375
  {
346
- $group: {
347
- _id: fields.length === 1 ? (dateFields.has(fields[0]) ? getDateFormat(fields[0], dateFormat) : `$${fields[0]}`) : groupId,
348
- count: { $sum: 1 }
349
- }
376
+ $group: groupStage
350
377
  }
351
378
  ];
352
379
  // Solo agregar lookups si hay campos de referencia
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "2.6.0",
6
+ "version": "2.9.0",
7
7
  "description": "Crud utils across modules",
8
8
  "main": "dist/index.js",
9
9
  "types": "types/index.d.ts",
@@ -22,10 +22,10 @@
22
22
  "author": "Cristian Incarnato & Drax Team",
23
23
  "license": "ISC",
24
24
  "dependencies": {
25
- "@drax/common-back": "^2.6.0",
25
+ "@drax/common-back": "^2.8.0",
26
26
  "@drax/common-share": "^2.0.0",
27
27
  "@drax/identity-share": "^2.0.0",
28
- "@drax/media-back": "^2.6.0",
28
+ "@drax/media-back": "^2.9.0",
29
29
  "@graphql-tools/load-files": "^7.0.0",
30
30
  "@graphql-tools/merge": "^9.0.4",
31
31
  "mongoose": "^8.23.0",
@@ -46,5 +46,5 @@
46
46
  "tsc-alias": "^1.8.10",
47
47
  "typescript": "^5.9.3"
48
48
  },
49
- "gitHead": "57830b50c2c9081b9d7e236d441ed9b2a3aca0ba"
49
+ "gitHead": "2bc9b59a45c762bd32403dce14db2693be34dcc7"
50
50
  }
@@ -219,6 +219,8 @@ class AbstractMongoRepository<T, C, U> implements IDraxCrud<T, C, U> {
219
219
 
220
220
  MongooseQueryFilter.applyFilters(query, filters)
221
221
 
222
+ // console.log("Paginate Query", query)
223
+
222
224
  const sort = MongooseSort.applySort(orderBy, order)
223
225
  const populate = this._populateFields
224
226
  const lean = this._lean
@@ -319,6 +321,7 @@ class AbstractMongoRepository<T, C, U> implements IDraxCrud<T, C, U> {
319
321
  const query = {}
320
322
 
321
323
  MongooseQueryFilter.applyFilters(query, filters)
324
+ // console.log("groupBy Query", query)
322
325
 
323
326
  // Obtener el schema para identificar campos de referencia y fechas
324
327
  const schema = this._model.schema
@@ -329,6 +332,13 @@ class AbstractMongoRepository<T, C, U> implements IDraxCrud<T, C, U> {
329
332
  const finalProjectFields: any = {count: 1, _id: 0}
330
333
  const refFields = new Set<string>()
331
334
  const dateFields = new Set<string>()
335
+ const numericFields = new Set<string>()
336
+ const groupFields: string[] = []
337
+ const numericInstances = new Set(['Number', 'Decimal128', 'Double', 'Int32', 'Long', 'BigInt'])
338
+ const totalGroupFields = fields.filter(field => {
339
+ const schemaPath = schema.path(field)
340
+ return !(schemaPath && numericInstances.has(schemaPath.instance))
341
+ }).length
332
342
 
333
343
  // Función para obtener el formato de fecha según el nivel de granularidad
334
344
  const getDateFormat = (field: string, format: string) => {
@@ -388,6 +398,15 @@ class AbstractMongoRepository<T, C, U> implements IDraxCrud<T, C, U> {
388
398
  fields.forEach(field => {
389
399
  const schemaPath = schema.path(field)
390
400
 
401
+ // Verificar si el campo es numérico: se agregará con $sum y no formará parte de la clave de agrupación
402
+ if (schemaPath && numericInstances.has(schemaPath.instance)) {
403
+ numericFields.add(field)
404
+ finalProjectFields[field] = 1
405
+ return
406
+ }
407
+
408
+ groupFields.push(field)
409
+
391
410
  // Verificar si el campo es de tipo Date
392
411
  if (schemaPath && schemaPath.instance === 'Date') {
393
412
  dateFields.add(field)
@@ -405,7 +424,7 @@ class AbstractMongoRepository<T, C, U> implements IDraxCrud<T, C, U> {
405
424
  const collectionName = refModelInstance.collection.name
406
425
 
407
426
  // Determinar el campo local correcto según si es un solo campo o múltiples
408
- const localField = fields.length === 1 ? '_id' : `_id.${fieldName}`
427
+ const localField = totalGroupFields === 1 ? '_id' : `_id.${fieldName}`
409
428
 
410
429
  lookupStages.push({
411
430
  $lookup: {
@@ -434,15 +453,15 @@ class AbstractMongoRepository<T, C, U> implements IDraxCrud<T, C, U> {
434
453
  })
435
454
 
436
455
  // Construir la proyección final para campos de fecha
437
- fields.forEach(field => {
456
+ groupFields.forEach(field => {
438
457
  if (dateFields.has(field)) {
439
- if (fields.length === 1) {
458
+ if (groupFields.length === 1) {
440
459
  finalProjectFields[field] = `$_id`
441
460
  } else {
442
461
  finalProjectFields[field] = `$_id.${field}`
443
462
  }
444
463
  } else if (!refFields.has(field)) {
445
- if (fields.length === 1) {
464
+ if (groupFields.length === 1) {
446
465
  finalProjectFields[field] = `$_id`
447
466
  } else {
448
467
  finalProjectFields[field] = `$_id.${field}`
@@ -450,13 +469,26 @@ class AbstractMongoRepository<T, C, U> implements IDraxCrud<T, C, U> {
450
469
  }
451
470
  })
452
471
 
472
+ const groupStage: any = {
473
+ _id: null,
474
+ count: {$sum: 1}
475
+ }
476
+
477
+ numericFields.forEach(field => {
478
+ groupStage[field] = {$sum: {$ifNull: [`$${field}`, 0]}}
479
+ })
480
+
481
+ if (groupFields.length === 1) {
482
+ const field = groupFields[0]
483
+ groupStage._id = dateFields.has(field) ? getDateFormat(field, dateFormat) : groupId[field]
484
+ } else if (groupFields.length > 1) {
485
+ groupStage._id = groupId
486
+ }
487
+
453
488
  const pipeline: any[] = [
454
489
  {$match: query},
455
490
  {
456
- $group: {
457
- _id: fields.length === 1 ? (dateFields.has(fields[0]) ? getDateFormat(fields[0], dateFormat) : `$${fields[0]}`) : groupId,
458
- count: {$sum: 1}
459
- }
491
+ $group: groupStage
460
492
  }
461
493
  ]
462
494