Google 云端点中的分页 + 数据存储 + Objectify
Pagination in Google cloud endpoints + Datastore + Objectify
我想 return 来自具有可选分页的端点的 "Posts" 列表。
每个查询需要 100 个结果。
我写的代码如下,它似乎不起作用。
我指的是 Objectify Wiki
中的示例
我知道的另一个选择是使用 query.offset(100);
但我在某处读到这只会加载整个 table 然后忽略前 100 个不是最佳的条目。
我想这一定是一个常见的用例,并且会有一个最佳解决方案。
public CollectionResponse<Post> getPosts(@Nullable @Named("cursor") String cursor,User auth) throws OAuthRequestException {
if (auth!=null){
Query<Post> query = ofy().load().type(Post.class).filter("isReviewed", true).order("-timeStamp").limit(100);
if (cursor!=null){
query.startAt(Cursor.fromWebSafeString(cursor));
log.info("Cursor received :" + Cursor.fromWebSafeString(cursor));
} else {
log.info("Cursor received : null");
}
QueryResultIterator<Post> iterator = query.iterator();
for (int i = 1 ; i <=100 ; i++){
if (iterator.hasNext()) iterator.next();
else break;
}
log.info("Cursor generated :" + iterator.getCursor());
return CollectionResponse.<Post>builder().setItems(query.list()).setNextPageToken(iterator.getCursor().toWebSafeString()).build();
} else throw new OAuthRequestException("Login please.");
}
这是一个使用 Offsets 的代码,似乎工作正常。
@ApiMethod(
name = "getPosts",
httpMethod = ApiMethod.HttpMethod.GET
)
public CollectionResponse<Post> getPosts(@Nullable @Named("offset") Integer offset,User auth) throws OAuthRequestException {
if (auth!=null){
if (offset==null) offset = 0;
Query<Post> query = ofy().load().type(Post.class).filter("isReviewed", true).order("-timeStamp").offset(offset).limit(LIMIT);
log.info("Offset received :" + offset);
log.info("Offset generated :" + (LIMIT+offset));
return CollectionResponse.<Post>builder().setItems(query.list()).setNextPageToken(String.valueOf(LIMIT + offset)).build();
} else throw new OAuthRequestException("Login please.");
}
尝试以下操作:
- 删除您的
for
循环——不确定它为什么在那里。但只需遍历您的列表并构建您要发回的项目列表。您应该坚持使用迭代器,而不是在一个循环中强制使用 100 个项目。
- 接下来,一旦你遍历了它,使用
iterator.getStartCursor()
作为游标的值。
一定要分配查询:
query = query.startAt(cursor);
Objectify 的 API 使用函数式风格。 startAt()
不改变对象。
我想 return 来自具有可选分页的端点的 "Posts" 列表。 每个查询需要 100 个结果。 我写的代码如下,它似乎不起作用。 我指的是 Objectify Wiki
中的示例我知道的另一个选择是使用 query.offset(100);
但我在某处读到这只会加载整个 table 然后忽略前 100 个不是最佳的条目。
我想这一定是一个常见的用例,并且会有一个最佳解决方案。
public CollectionResponse<Post> getPosts(@Nullable @Named("cursor") String cursor,User auth) throws OAuthRequestException {
if (auth!=null){
Query<Post> query = ofy().load().type(Post.class).filter("isReviewed", true).order("-timeStamp").limit(100);
if (cursor!=null){
query.startAt(Cursor.fromWebSafeString(cursor));
log.info("Cursor received :" + Cursor.fromWebSafeString(cursor));
} else {
log.info("Cursor received : null");
}
QueryResultIterator<Post> iterator = query.iterator();
for (int i = 1 ; i <=100 ; i++){
if (iterator.hasNext()) iterator.next();
else break;
}
log.info("Cursor generated :" + iterator.getCursor());
return CollectionResponse.<Post>builder().setItems(query.list()).setNextPageToken(iterator.getCursor().toWebSafeString()).build();
} else throw new OAuthRequestException("Login please.");
}
这是一个使用 Offsets 的代码,似乎工作正常。
@ApiMethod(
name = "getPosts",
httpMethod = ApiMethod.HttpMethod.GET
)
public CollectionResponse<Post> getPosts(@Nullable @Named("offset") Integer offset,User auth) throws OAuthRequestException {
if (auth!=null){
if (offset==null) offset = 0;
Query<Post> query = ofy().load().type(Post.class).filter("isReviewed", true).order("-timeStamp").offset(offset).limit(LIMIT);
log.info("Offset received :" + offset);
log.info("Offset generated :" + (LIMIT+offset));
return CollectionResponse.<Post>builder().setItems(query.list()).setNextPageToken(String.valueOf(LIMIT + offset)).build();
} else throw new OAuthRequestException("Login please.");
}
尝试以下操作:
- 删除您的
for
循环——不确定它为什么在那里。但只需遍历您的列表并构建您要发回的项目列表。您应该坚持使用迭代器,而不是在一个循环中强制使用 100 个项目。 - 接下来,一旦你遍历了它,使用
iterator.getStartCursor()
作为游标的值。
一定要分配查询:
query = query.startAt(cursor);
Objectify 的 API 使用函数式风格。 startAt()
不改变对象。