如何在左连接 table 列上过滤时对结果进行分页
How to paginate results when filtering on left join table column
让我们定义例如这些实体:
@Entity()
export class Author {
@OneToMany(() => Book, book => book.author)
books = new Collection<Book>(this);
}
@Entity()
export class Book {
@Property()
name: string;
@ManyToOne()
author: Author;
}
const authors = await authorRepository.find({ books: {name: 'Test'} }, {
limit: 10
});
如您所见,我想 select 所有拥有名称为 'Test' 的作者,但这将生成以下查询:
select `e0`.* from `author` as `e0`
left join `book` as `e1` on `e0`.`id` = `e1`.`author_id`
where `e1`.`name` = 'Test' limit 10
问题是当我有超过 2 位作者并且他们每个人都有超过 10 本名称为 'Test' 的书时,由于限制条款,此查询将 return 只有第一作者。
我不确定这是 ORM 中的错误还是预期的行为。
解决这个问题的一种方法是 select 所有没有限制子句的行,并像在休眠中一样在内存中进行分页,但我不确定在非常大的情况下会使用多少内存表,这可能会在处理它们时阻塞 NodeJS 中的事件循环。
您可以回退到此处的查询构建器以应用 group by 子句:
const qb = await authorRepository.createQueryBuilder('a');
qb.select('a.*').where({ books: { name: 'Test' } }).limit(10).groupBy('a.id');
const authors = await qb.getResult();
会考虑如何通过EM/repository API直接支持这个用例。
让我们定义例如这些实体:
@Entity()
export class Author {
@OneToMany(() => Book, book => book.author)
books = new Collection<Book>(this);
}
@Entity()
export class Book {
@Property()
name: string;
@ManyToOne()
author: Author;
}
const authors = await authorRepository.find({ books: {name: 'Test'} }, {
limit: 10
});
如您所见,我想 select 所有拥有名称为 'Test' 的作者,但这将生成以下查询:
select `e0`.* from `author` as `e0`
left join `book` as `e1` on `e0`.`id` = `e1`.`author_id`
where `e1`.`name` = 'Test' limit 10
问题是当我有超过 2 位作者并且他们每个人都有超过 10 本名称为 'Test' 的书时,由于限制条款,此查询将 return 只有第一作者。
我不确定这是 ORM 中的错误还是预期的行为。
解决这个问题的一种方法是 select 所有没有限制子句的行,并像在休眠中一样在内存中进行分页,但我不确定在非常大的情况下会使用多少内存表,这可能会在处理它们时阻塞 NodeJS 中的事件循环。
您可以回退到此处的查询构建器以应用 group by 子句:
const qb = await authorRepository.createQueryBuilder('a');
qb.select('a.*').where({ books: { name: 'Test' } }).limit(10).groupBy('a.id');
const authors = await qb.getResult();
会考虑如何通过EM/repository API直接支持这个用例。