【问题标题】:Pagination in Google cloud endpoints + Datastore + Objectify谷歌云端点 + 数据存储 + Objectify 中的分页
【发布时间】:2016-02-07 06:52:07
【问题描述】:

我想从带有可选分页的端点返回“帖子”列表。 每个查询我需要 100 个结果。 我写的代码如下,它似乎不起作用。 我指的是Objectify Wiki的一个例子

我知道的另一个选项是使用query.offset(100); 但我在某处读到这只是加载整个表,然后忽略前 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.");
    }

这是一个使用偏移量的代码,似乎工作正常。

@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.");
    }

【问题讨论】:

    标签: google-app-engine pagination google-cloud-endpoints objectify google-cloud-datastore


    【解决方案1】:

    一定要指定查询:

    query = query.startAt(cursor);
    

    Objectify 的 API 使用函数式风格。 startAt() 不会改变对象。

    【讨论】:

    • 这种方式比使用offsets效率高吗?
    • 是的,戏剧性如此
    【解决方案2】:

    尝试以下方法:

    1. 删除您的for 循环——不知道为什么会出现。但只需遍历您的列表并构建您想要发回的项目列表。您应该坚持使用迭代器,而不是在循环中强制使用 100 个项目。
    2. 接下来,一旦你遍历它,使用iterator.getStartCursor() 作为光标的值。

    【讨论】:

    • iterator.getStartCursor() 方法在 Objectify 中不可用。
    • 我想要一种方法来完全避免我的方法中的循环。我添加的原因只是为了生成下一页光标。我想摆脱它。最终我想依靠 Memcache 来提高性能。因此,像带有偏移量的单一查询会表现得更好。
    • 你不能在没有迭代器的情况下使用游标,因为列表(显然)不公开迭代器。您将不得不对游标查询使用循环。这里有一个如何使用游标的例子:github.com/objectify/objectify/wiki/Queries#cursors
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-17
    • 1970-01-01
    • 2019-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多