Aggregated queries #1 (#8345)

First step of https://github.com/twentyhq/twenty/issues/6868

Adds min.., max.. queries for DATETIME fields
adds min.., max.., avg.., sum.. queries for NUMBER fields 

(count distinct operation and composite fields such as CURRENCY handling
will be dealt with in a future PR)

<img width="1422" alt="Capture d’écran 2024-11-06 à 15 48 46"
src="https://github.com/user-attachments/assets/4bcdece0-ad3e-4536-9720-fe4044a36719">

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Weiko <corentin@twenty.com>
This commit is contained in:
Marie
2024-11-14 18:05:05 +01:00
committed by GitHub
parent c966533f26
commit a799370483
93 changed files with 1590 additions and 1178 deletions
@@ -0,0 +1,84 @@
import { GraphQLISODateTime } from '@nestjs/graphql';
import { GraphQLFloat, GraphQLInt, GraphQLScalarType } from 'graphql';
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { capitalize } from 'src/utils/capitalize';
enum AGGREGATION_OPERATIONS {
min = 'MIN',
max = 'MAX',
avg = 'AVG',
sum = 'SUM',
count = 'COUNT',
}
export type AggregationField = {
type: GraphQLScalarType;
description: string;
fromField: string;
aggregationOperation: AGGREGATION_OPERATIONS;
};
export const getAvailableAggregationsFromObjectFields = (
fields: FieldMetadataInterface[],
): Record<string, AggregationField> => {
return fields.reduce<Record<string, AggregationField>>((acc, field) => {
acc['totalCount'] = {
type: GraphQLInt,
description: `Total number of records in the connection`,
fromField: 'id',
aggregationOperation: AGGREGATION_OPERATIONS.count,
};
if (field.type === FieldMetadataType.DATE_TIME) {
acc[`min${capitalize(field.name)}`] = {
type: GraphQLISODateTime,
description: `Oldest date contained in the field ${field.name}`,
fromField: field.name,
aggregationOperation: AGGREGATION_OPERATIONS.min,
};
acc[`max${capitalize(field.name)}`] = {
type: GraphQLISODateTime,
description: `Most recent date contained in the field ${field.name}`,
fromField: field.name,
aggregationOperation: AGGREGATION_OPERATIONS.max,
};
}
if (field.type === FieldMetadataType.NUMBER) {
acc[`min${capitalize(field.name)}`] = {
type: GraphQLFloat,
description: `Minimum amount contained in the field ${field.name}`,
fromField: field.name,
aggregationOperation: AGGREGATION_OPERATIONS.min,
};
acc[`max${capitalize(field.name)}`] = {
type: GraphQLFloat,
description: `Maximum amount contained in the field ${field.name}`,
fromField: field.name,
aggregationOperation: AGGREGATION_OPERATIONS.max,
};
acc[`avg${capitalize(field.name)}`] = {
type: GraphQLFloat,
description: `Average amount contained in the field ${field.name}`,
fromField: field.name,
aggregationOperation: AGGREGATION_OPERATIONS.avg,
};
acc[`sum${capitalize(field.name)}`] = {
type: GraphQLFloat,
description: `Sum of amounts contained in the field ${field.name}`,
fromField: field.name,
aggregationOperation: AGGREGATION_OPERATIONS.sum,
};
}
return acc;
}, {});
};