Add deletedAt to foreignKey indexes (#7133)

We had to remove soft-deletion on default filters due to the missing
indexes. We now generate composite indexes with the foreign key
containing the deletedAt column as well which should improve
performances
This commit is contained in:
Weiko
2024-09-19 11:23:40 +02:00
committed by GitHub
parent 9d5b9f8415
commit e0ada0a8ee
5 changed files with 46 additions and 9 deletions

View File

@ -30,16 +30,48 @@ export class GraphqlQueryParser {
this.fieldMetadataMap = fieldMetadataMap;
}
parseFilter(
recordFilter: RecordFilter,
): FindOptionsWhere<ObjectLiteral> | FindOptionsWhere<ObjectLiteral>[] {
parseFilter(recordFilter: RecordFilter): {
parsedFilters:
| FindOptionsWhere<ObjectLiteral>
| FindOptionsWhere<ObjectLiteral>[];
withDeleted: boolean;
} {
const graphqlQueryFilterParser = new GraphqlQueryFilterParser(
this.fieldMetadataMap,
);
const parsedFilter = graphqlQueryFilterParser.parse(recordFilter);
return parsedFilter;
const hasDeletedAtFilter = this.checkForDeletedAtFilter(parsedFilter);
return {
parsedFilters: parsedFilter,
withDeleted: hasDeletedAtFilter,
};
}
private checkForDeletedAtFilter(
filter: FindOptionsWhere<ObjectLiteral> | FindOptionsWhere<ObjectLiteral>[],
): boolean {
if (Array.isArray(filter)) {
return filter.some(this.checkForDeletedAtFilter);
}
for (const [key, value] of Object.entries(filter)) {
if (key === 'deletedAt') {
return true;
}
if (typeof value === 'object' && value !== null) {
if (
this.checkForDeletedAtFilter(value as FindOptionsWhere<ObjectLiteral>)
) {
return true;
}
}
}
return false;
}
parseOrder(

View File

@ -79,7 +79,8 @@ export class GraphqlQueryFindManyResolverService {
args.orderBy ?? [],
isForwardPagination,
);
const where = graphqlQueryParser.parseFilter(args.filter ?? ({} as Filter));
const { parsedFilters: where, withDeleted } =
graphqlQueryParser.parseFilter(args.filter ?? ({} as Filter));
const cursor = this.getCursor(args);
const limit = args.first ?? args.last ?? QUERY_MAX_RECORDS;
@ -92,10 +93,11 @@ export class GraphqlQueryFindManyResolverService {
order,
select,
take: limit + 1,
withDeleted,
};
const totalCount = isDefined(selectedFields.totalCount)
? await repository.count({ where })
? await repository.count({ where, withDeleted })
: 0;
if (cursor) {

View File

@ -63,11 +63,13 @@ export class GraphqlQueryFindOneResolverService {
objectMetadataItem,
selectedFields,
);
const where = graphqlQueryParser.parseFilter(args.filter ?? ({} as Filter));
const { parsedFilters: where, withDeleted } =
graphqlQueryParser.parseFilter(args.filter ?? ({} as Filter));
const objectRecord = (await repository.findOne({
where,
select,
withDeleted,
})) as ObjectRecord;
const limit = QUERY_MAX_RECORDS;

View File

@ -38,9 +38,9 @@ export function WorkspaceIndex(
metadataArgsStorage.addIndexes({
name: `IDX_${generateDeterministicIndexName([
convertClassNameToObjectMetadataName(target.constructor.name),
propertyKey.toString(),
...[propertyKey.toString(), 'deletedAt'],
])}`,
columns: [propertyKey.toString()],
columns: [propertyKey.toString(), 'deletedAt'],
target: target.constructor,
gate,
});

View File

@ -79,6 +79,7 @@ export class EntitySchemaColumnFactory {
nullable: fieldMetadata.isNullable,
createDate: key === 'createdAt',
updateDate: key === 'updatedAt',
deleteDate: key === 'deletedAt',
array: fieldMetadata.type === FieldMetadataType.MULTI_SELECT,
default: defaultValue,
};