Skip to content

Commit 2b534b3

Browse files
committed
feat: enhance MongoDB connector to support typed aggregations and improve groupBy handling
1 parent 70366c6 commit 2b534b3

1 file changed

Lines changed: 31 additions & 18 deletions

File tree

adminforth/dataConnectors/mongo.ts

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -309,8 +309,8 @@ class MongoConnector extends AdminForthBaseConnector implements IAdminForthDataS
309309
async getAggregateWithOriginalTypes({ resource, filters, aggregations, groupBy }: {
310310
resource: AdminForthResource;
311311
filters: IAdminForthAndOrFilter;
312-
aggregations: any;
313-
groupBy?: any;
312+
aggregations: { [alias: string]: IAggregationRule };
313+
groupBy?: IGroupByRule;
314314
}): Promise<Array<{ group?: string, [key: string]: any }>> {
315315

316316
const collection = this.client.db().collection(resource.table);
@@ -320,27 +320,33 @@ class MongoConnector extends AdminForthBaseConnector implements IAdminForthDataS
320320
let groupId: any = null;
321321

322322
if (groupBy?.type === 'field') {
323-
groupId = `$${groupBy.field}`;
323+
const g = groupBy as IGroupByField;
324+
groupId = `$${g.field}`;
324325
}
325326

326327
if (groupBy?.type === 'date_trunc') {
327-
const tz = groupBy.timezone ?? 'UTC';
328-
const dateTruncSpec: any = { date: `$${groupBy.field}`, unit: groupBy.truncation, timezone: tz,};
329-
if (groupBy.truncation === 'week') {
328+
const g = groupBy as IGroupByDateTrunc;
329+
const tz = g.timezone ?? 'UTC';
330+
const dateTruncSpec: any = {
331+
date: `$${g.field}`,
332+
unit: g.truncation,
333+
timezone: tz,
334+
};
335+
if (g.truncation === 'week') {
330336
dateTruncSpec.startOfWeek = 'Mon';
331337
}
332-
groupId = { $dateTrunc: dateTruncSpec,};
338+
groupId = { $dateTrunc: dateTruncSpec };
333339
}
334340

335-
const groupStage: any = {
341+
const groupStage: Record<string, any> = {
336342
_id: groupId,
337343
};
338344

339-
for (const [alias, rule] of Object.entries(aggregations) as any) {
345+
for (const [alias, rule] of Object.entries(aggregations)) {
340346
switch (rule.operation) {
341347
case 'count': groupStage[alias] = { $sum: 1 }; break;
342348
case 'sum': groupStage[alias] = { $sum: { $toDouble: `$${rule.field}` } }; break;
343-
case 'avg': groupStage[alias] = { $avg: { $toDouble: `$${rule.field}` } }; break;
349+
case 'avg': groupStage[alias] = { $avg: { $toDouble: `$${rule.field}` } }; break;
344350
case 'min': groupStage[alias] = { $min: { $toDouble: `$${rule.field}` } }; break;
345351
case 'max': groupStage[alias] = { $max: { $toDouble: `$${rule.field}` } }; break;
346352
case 'median': groupStage[alias] = { $push: { $toDouble: `$${rule.field}` } }; break;
@@ -358,18 +364,23 @@ class MongoConnector extends AdminForthBaseConnector implements IAdminForthDataS
358364
pipeline.push({
359365
$project: {
360366
_id: 0,
361-
group: !groupBy ? "$$REMOVE" : groupBy.type === 'date_trunc' ? {
367+
group: !groupBy ? "$$REMOVE" : (groupBy.type === 'date_trunc' ? {
362368
$cond: {
363369
if: { $eq: [{ $type: "$_id" }, "date"] },
364-
then: { $dateToString: { format: "%Y-%m-%d", date: "$_id", timezone: groupBy?.timezone ?? 'UTC' } },
365-
else: "$_id"
366-
}
370+
then: {
371+
$dateToString: {
372+
format: "%Y-%m-%d",
373+
date: "$_id",
374+
timezone: (groupBy as IGroupByDateTrunc).timezone ?? 'UTC'
375+
}
376+
},
377+
else: "$_id"
367378
}
368-
: "$_id",
379+
} : "$_id"),
369380
...Object.fromEntries(
370381
Object.keys(groupStage)
371-
.filter(k => k !== '_id')
372-
.map(k => [k, `$${k}`])
382+
.filter(k => k !== '_id')
383+
.map(k => [k, `$${k}`])
373384
),
374385
},
375386
});
@@ -385,7 +396,9 @@ class MongoConnector extends AdminForthBaseConnector implements IAdminForthDataS
385396

386397
const result = await collection.aggregate(pipeline).toArray();
387398

388-
const medianAliases = Object.keys(aggregations).filter(alias => aggregations[alias].operation === 'median');
399+
const medianAliases = Object.keys(aggregations).filter(
400+
alias => aggregations[alias].operation === 'median'
401+
);
389402

390403
return result.map(row => {
391404
medianAliases.forEach(alias => {

0 commit comments

Comments
 (0)