Skip to content

Commit

Permalink
perf(query-typeorm): Don't use skip/take when filtering for one to on…
Browse files Browse the repository at this point in the history
…e and many to one relations
  • Loading branch information
TriPSs committed Feb 19, 2023
1 parent 1f5ab0d commit cdd06b6
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 18 deletions.
45 changes: 30 additions & 15 deletions packages/query-typeorm/src/query/filter-query.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ export class FilterQueryBuilder<Entity> {
* @param query - the query to apply.
*/
public select(query: Query<Entity>): SelectQueryBuilder<Entity> {
const hasFilterRelations = this.filterHasRelations(query.filter)
let qb = this.createQueryBuilder()
qb = this.applyRelationJoinsRecursive(
qb,
Expand All @@ -87,24 +86,12 @@ export class FilterQueryBuilder<Entity> {
)
qb = this.applyFilter(qb, query.filter, qb.alias)
qb = this.applySorting(qb, query.sorting, qb.alias)
qb = this.applyPaging(qb, query.paging, hasFilterRelations)
qb = this.applyPaging(qb, query.paging, this.shouldUseSkipTake(query.filter))
return qb
}

public selectById(id: string | number | (string | number)[], query: Query<Entity>): SelectQueryBuilder<Entity> {
const hasFilterRelations = this.filterHasRelations(query.filter)

let qb = this.createQueryBuilder()
qb = this.applyRelationJoinsRecursive(
qb,
this.getReferencedRelationsRecursive(this.repo.metadata, query.filter, query.relations),
query.relations
)
qb = qb.andWhereInIds(id)
qb = this.applyFilter(qb, query.filter, qb.alias)
qb = this.applySorting(qb, query.sorting, qb.alias)
qb = this.applyPaging(qb, query.paging, hasFilterRelations)
return qb
return this.select(query).andWhereInIds(id)
}

public aggregate(query: Query<Entity>, aggregate: AggregateQuery<Entity>): SelectQueryBuilder<Entity> {
Expand Down Expand Up @@ -300,6 +287,34 @@ export class FilterQueryBuilder<Entity> {
return getFilterFields(filter).filter((f) => relationNames.includes(f)).length > 0
}

/**
* Checks if the query should use skip/take instead of limit/offset
*/
private shouldUseSkipTake(filter?: Filter<Entity>): boolean {
if (!filter) {
return false
}

return (
getFilterFields(filter).filter((field) => {
const relation = this.repo.metadata.relations.find(({ propertyName }) => propertyName === field)

if (!relation) {
return false
}

if (!relation || relation.isOneToOne || relation.isManyToOne) {
return false
// } else if (relation.isOneToMany) {
// TODO
// return false
} else {
return true
}
}).length > 0
)
}

public getReferencedRelationsRecursive(
metadata: EntityMetadata,
filter: Filter<unknown> = {},
Expand Down
6 changes: 3 additions & 3 deletions packages/query-typeorm/src/services/relation-query.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ export abstract class RelationQueryService<Entity> {
* @param relationId - The id of the relation to set on the entity.
* @param opts - Additional options
*/
async setRelation<Relation>(
public async setRelation<Relation>(
relationName: string,
id: string | number,
relationId: string | number,
Expand All @@ -276,7 +276,7 @@ export abstract class RelationQueryService<Entity> {
* @param relationIds - The ids of the relations to add.
* @param opts - Additional options
*/
async removeRelations<Relation>(
public async removeRelations<Relation>(
relationName: string,
id: string | number,
relationIds: (string | number)[],
Expand All @@ -298,7 +298,7 @@ export abstract class RelationQueryService<Entity> {
* @param relationName - The name of the relation to query for.
* @param relationId - The id of the relation to set on the entity.
*/
async removeRelation<Relation>(
public async removeRelation<Relation>(
relationName: string,
id: string | number,
relationId: string | number,
Expand Down

0 comments on commit cdd06b6

Please sign in to comment.