@pujansrt/data-genie
Version:
High performant ETL engine written in TypeScript
66 lines (65 loc) • 2.71 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.GroupByReader = void 0;
const transformers_1 = require("../transformers/transformers");
class GroupByReader extends transformers_1.DataTransformer {
constructor(reader, groupByField) {
super(reader);
this.aggregations = [];
this.groupByField = groupByField;
}
count(outputField) {
this.aggregations.push({ type: 'count', outputField });
return this;
}
sum(sourceField, outputField) {
this.aggregations.push({ type: 'sum', sourceField, outputField });
return this;
}
max(sourceField, outputField) {
this.aggregations.push({ type: 'max', sourceField, outputField });
return this;
}
min(sourceField, outputField) {
this.aggregations.push({ type: 'min', sourceField, outputField });
return this;
}
avg(sourceField, outputField) {
this.aggregations.push({ type: 'avg', sourceField, outputField });
return this;
}
async *read() {
const groupedData = new Map();
for await (const record of this.reader.read()) {
const keyValue = record[this.groupByField];
if (!groupedData.has(keyValue)) {
groupedData.set(keyValue, { records: [], aggregates: { [this.groupByField]: keyValue } });
}
groupedData.get(keyValue).records.push(record);
}
for (const [key, { records, aggregates }] of groupedData.entries()) {
for (const agg of this.aggregations) {
switch (agg.type) {
case 'count':
aggregates[agg.outputField] = records.length;
break;
case 'sum':
aggregates[agg.outputField] = records.reduce((sum, r) => sum + (parseFloat(r[agg.sourceField]) || 0), 0);
break;
case 'max':
aggregates[agg.outputField] = Math.max(...records.map((r) => parseFloat(r[agg.sourceField]) || 0));
break;
case 'min':
aggregates[agg.outputField] = Math.min(...records.map((r) => parseFloat(r[agg.sourceField]) || 0));
break;
case 'avg':
const sum = records.reduce((s, r) => s + (parseFloat(r[agg.sourceField]) || 0), 0);
aggregates[agg.outputField] = records.length > 0 ? sum / records.length : 0;
break;
}
}
yield aggregates;
}
}
}
exports.GroupByReader = GroupByReader;