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:
@ -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(
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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,
|
||||
});
|
||||
|
||||
@ -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,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user