如何使用nextToken进行分页?

问题描述 投票:0回答:2

我在帖子底部的问题需要一些背景信息。 DynamoDB 中有两个具有以下架构的表。

type Post @model {
  id: ID!
  author: String!
  comments: [Comment] @hasMany
}

type Comment @model {
  id: ID!
  description: String!
  post: Post! @belongsTo
}

Post table
有125个帖子。
Comment table
有 3000 多条评论。获取全部 125 个帖子只需不到 5 秒。获取所有 3000 多条评论(限制为 1000 条)并分页需要超过 10 秒。

在每个

Post
对象中,最多包含 100 条评论。假设每个帖子有 100 多条评论,当我们获取所有 125 篇帖子时,我们会在 5 秒内获得 3000 多条评论中的 1,250 条,而当我们从评论表中获取所有评论时,需要等待超过 10 秒。

Comment Table
获取的代码需要超过 10 秒。

    do {
      const result = await API.graphql(graphqlOperation(listComments, { limit: 1000, nextToken }));
      const tokens = result.data.listComments.items;
      allEvents.push(...tokens);
      nextToken = result.data.listComments.nextToken;
    } while (nextToken);

为了加快我们的应用程序获取所有评论(目标)所需的时间,我尝试从

comment
对象中提取所有
Post
数据,因为我们获取所有 Post 对象的速度要快得多。我们的想法是,如果我们很快从帖子中获得 1250 条评论,我们就可以从 Post.comments.nextToken 中获取 nextToken。 (100 条评论的数组位于 Post.comments.items),然后点击上面相同的 graphql 函数。但是,执行此操作时,它会返回以下分页错误。

 error in fetchAllCommentsAPI: {"data":{"listComments":null},"errors":[{"path":["listComments"],"data":null,"errorType":"IllegalArgument","errorInfo":null,"locations":[{"line":2,"column":3,"sourceName":null}],"message":"Invalid pagination token given."}]}

我认为这可能是因为我们需要为我们正在获取的特定帖子添加过滤器,但这给出了相同的错误。

向我的 nextToken graphql 调用添加过滤器会导致错误:

const result = await API.graphql(graphqlOperation(listComments, { filter: { commentPostId: { eq: postId } }, nextToken })); // where commentPostId is the id of the Post.

我不明白为什么会收到该错误,我认为 nextToken 会带您进入该过滤页面。

问题

  1. 在过滤特定帖子的同时获取评论时如何使用 nextToken?

  2. 是否有更好的方法来有效地获取所有评论数据/从 Post 对象中提取是不好的做法?

javascript amazon-web-services react-native graphql amazon-dynamodb
2个回答
4
投票

来自过滤查询的令牌只能与相同的过滤参数一起使用。当您获得

Post.comments.nextToken
时,它特定于 Post 表中关系查询的分页。当您尝试将此标记与
listComments
一起使用时,会失败,因为它完全是不同的查询上下文。您可以尝试实现以下功能,以使用帖子表分页获取特定帖子的评论:-

const getPostWithComments = async (postId) => {
  let nextToken = null;
  let allComments = [];
  
  do {
    const result = await API.graphql(
      graphqlOperation(getPost, {
        id: postId,
        commentsLimit: 100,
        commentsNextToken: nextToken
      })
    );
    
    const post = result.data.getPost;
    allComments.push(...post.comments.items);
    nextToken = post.comments.nextToken;
  } while (nextToken);
  
  return allComments;
};
  1. 在初始 Post 查询中使用
    Post.comments
    来获取评论很好,因为它更快、更高效(5 秒与 10 秒)。因为无论如何您都会将数据作为 Post 查询的一部分获取。但对于后续数据(评论),建议实现分页,以便仅在需要时加载附加评论,也许当用户滚动或请求更多时。

0
投票
const getCommentsForPost = async (postId) => {
  // This is assuming that the postId is not null
  let nextToken = null;
  let allComments = [];

  do {
    const result = await API.graphql(
    graphqlOperation(listComments, { filter: { 
       commentPostId: { eq: postId } 
    // No need for limits
      }, 
     nextToken 
     })
   );

const comments = result.data.listComments.items;
allComments.push(...comments);
nextToken = result.data.listComments.nextToken;
} while (nextToken);

return allComments;
};

这应该可以获取特定帖子的评论,没有任何错误。另外,您能否澄清一下,您是否仅在查看单个帖子详细信息时才收到评论,或者您正在尝试获取多个帖子评论。

不管怎样,这个功能仍然可以获得你需要的评论

© www.soinside.com 2019 - 2024. All rights reserved.