使用TypeORM getManyWithCount如何生成用于分页的PageInfo

时间:2019-03-22 14:21:35

标签: graphql apollo apollo-client relay typeorm

我正在为GraphQL服务器实现中继样式分页,并使用出色的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 个答案:

答案 0 :(得分:1)

这将非常有用,但是请记住,totalEntitiesCount并不是表中所有条目的计数,而是仅与您的光标条件相匹配的条目(note.notedAt > :afternote.notedAt <= :before)的计数。 gb.getManyAndCount()在内部删除了所有按顺序,限制,跳过等顺序,但保留了条件(请参见this file)。

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

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

它仍然是WIP,我尚未对其进行测试。