TypeORM как использовать пагинацию в QueryBuilder
- БД: MS SQL
- typeorm: ^0.2.34
- Back: NestJS
У меня был запрос через find с пагинацией, который работал как надо:
const data = await this.docRepository.find({
relations: ['user', 'user.project'],
skip: limit * (page - 1),
take: limit,
order: {
create_at: 'DESC'
}
})
но была необходимость сделать orderBy по полю из relations ('user.project.creat_at': 'DESC') и как я выяснил через find это сделать невозможно. Поэтому я написал тот же запрос через QueryBuilder:
const data = await this.docRepository
.createQueryBuilder('doc')
.leftJoinAndSelect('doc.user', 'user')
.leftJoinAndSelect('user.project', 'project')
.orderBy({
'doc.create_at': 'DESC',
'project.create_at': 'DESC'
})
.limit(limit * (page - 1))
.offset(limit)
.getMany()
И тут проблема именно с пагинацией, если find сначала подготавливает результат вместе с relations а уже потом применяет разбиение на страницы, то QueryBuilder такого не делает и если в запросе есть leftJoinAndSelect, то он не будет сначала группировать связи а сразу обрежет результат, что является проблемой.
Подскажите, как решить вопрос с пагинацией на уровне SQL-запроса? Либо есть какие-то отдельные инструменты для этого?
Ответы (2 шт):
Как вариант методом JS есть такое решение, может кому пригодиться:
const dataAll = await this.docRepository
.createQueryBuilder('doc')
.leftJoinAndSelect('doc.user', 'user')
.leftJoinAndSelect('user.project', 'project')
.orderBy({
'doc.create_at': 'DESC',
'project.create_at': 'DESC'
})
.getMany()
const data = dataAll.slice((limit * (page - 1)), (limit * page))
Пример из документации с переводом
Применение пагинации:
const users = await getRepository(User)
.createQueryBuilder("user")
.leftJoinAndSelect("user.photos", "photo")
.skip(5)
.take(10)
.getMany();
Этот запрос пропустит первых 5 пользователей (.skip(5)) и получит следующие 10 за ними (.take(10))