使用 TypeORM getManyWithCount 如何生成 PageInfo 进行分页

Posted

技术标签:

【中文标题】使用 TypeORM getManyWithCount 如何生成 PageInfo 进行分页【英文标题】:With TypeORM getManyWithCount how to generate a PageInfo for pagination 【发布时间】:2019-08-13 13:29:15 【问题描述】:

我正在为 GraphQL 服务器实现 Relay 样式的分页,并使用出色的 TypeORM 库。

我想找到查询后创建 PageInfo 对象的最佳方法:

type PageInfo 
  endCursor: String
  hasNextPage: Boolean!
  hasPreviousPage: Boolean!
  startCursor: String

if (before) 
  qb = qb.andWhere('note.notedAt <=(:before)',  before );


if (after) 
  qb = qb.andWhere('note.notedAt >(:after)',  after );


qb = qb.take(args.take)
const [entities, totalEntitesCount] = qb.getManyWithCount()

因此,有了这些信息,我们如何计算 hasNextPagehasPreviousPage

我目前的想法:

function createPageInfo(
  noteEdges: Array< node: Note; cursor: Date >,
  totalCount: number,
  findOptions: NoteFindOptions
) 

  let hasNextPage: boolean;
  let hasPreviousPage: boolean;

  if(findOptions.after) 
    hasPreviousPage = true;
    hasNextPage = (noteEdges.length < totalCount)
   else if (findOptions.before) 
    hasNextPage = true;
    hasPreviousPage = (noteEdges.length < totalCount)
   else 
    hasPreviousPage = false;
    hasNextPage = (noteEdges.length < totalCount)
  

  return 
    startCursor: noteEdges[0].cursor,
    endCursor: noteEdges[noteEdges.length - 1].cursor,
    hasNextPage,
    hasPreviousPage
  ;


【问题讨论】:

【参考方案1】:

这几乎可以工作,但请记住,totalEntitiesCount 不是表中所有条目的计数,而只是那些与您的光标条件匹配的条目(note.notedAt &gt; :afternote.notedAt &lt;= :before)。 gb.getManyAndCount() 在内部删除任何 orderBy、limit、skip 等,但保留 where 条件(请参阅 this file)。

如果在before / after 光标上中继分别确定hasNext / hasPrev 也是可以的。如果您将表中的第一个 ID 或日期传递给 after 光标,您仍然会得到 hasPreviousPage = true,但实际上不会有。

您可以在this gist 中看到我对此的看法。这个想法是先查询结果,然后为结果前后的总计数和项目创建计数查询。在应用 where 条件之前克隆计数查询。这允许保留任何先前的条件,但避免光标条件。作为奖励,您将获得下一个/上一个项目的计数。

它仍然是 WIP,我还没有测试它。

【讨论】:

以上是关于使用 TypeORM getManyWithCount 如何生成 PageInfo 进行分页的主要内容,如果未能解决你的问题,请参考以下文章

typeorm中最简单的事务使用typeorm系列

typeorm中最简单的事务使用typeorm系列

typeorm中最简单的事务使用typeorm系列

使用 TypeOrm 中的关系更新表

TypeOrm - NestJS 使用 queryBuilder

TypeORM:使用自定义属性查询多对多