我们将数据存储在Google Cloud Datastore中。我们希望为用户提供API。 我们的API分页规范与github API相同。我们希望用户使用页面参数。
分页规范
e.g.
Link: <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=15>; rel="next",
<https://api.github.com/search/code?q=addClass+user%3Amozilla&page=34>; rel="last",
<https://api.github.com/search/code?q=addClass+user%3Amozilla&page=1>; rel="first",
<https://api.github.com/search/code?q=addClass+user%3Amozilla&page=13>; rel="prev"
https://developer.github.com/guides/traversing-with-pagination/
API
End-Users <--- Backend Code (PHP) <--- Google Cloud Datastore
如您所知,Google Cloud Datastore建议使用游标来提高性能和成本。但我们不希望最终用户使用游标。最终用户是否可能使用整数页码而不是游标?后端使用光标?
我们使用Google的PHP客户端。
答案 0 :(得分:4)
我相信你可以通过使用GQL来获得类似OFFSET
的东西,但是这样的操作会花费你很多钱(相当于LIMIT 1000, 10
会算作 1,010次读取强> - 不仅仅是你实际回来的10个。)
OFFSET
的费用假设您的页面大小为10个项目并且用户要求跳转到第5页。您需要查询前40个实体,获取光标并再次运行查询,现在提供光标并限制为10
建议您在第一个查询中使用keys_only=True
进行提取。这样你就可以:
答案 1 :(得分:2)
Google建议使用游标,并在其文档中有一个示例。 https://cloud.google.com/datastore/docs/concepts/queries#cursors_limits_and_offsets
const pageSize = 5
query := datastore.NewQuery("Tasks").Limit(pageSize)
if cursorStr != "" {
cursor, err := datastore.DecodeCursor(cursorStr)
if err != nil {
log.Fatalf("Bad cursor %q: %v", cursorStr, err)
}
query = query.Start(cursor)
}
// Read the tasks.
var tasks []Task
var task Task
it := client.Run(ctx, query)
_, err := it.Next(&task)
for err == nil {
tasks = append(tasks, task)
_, err = it.Next(&task)
}
if err != iterator.Done {
log.Fatalf("Failed fetching results: %v", err)
}
// Get the cursor for the next page of results.
nextCursor, err := it.Cursor()
答案 2 :(得分:0)
我不确定 GCloud 数据存储区的光标是否可用于用户需要“跳转”到不同页码的分页实现。这是我在项目中实现数据存储分页的方式:
给定一个现有的查询(排序、过滤等),一个“偏移量”(一个数字)和一个“限制”(一个数字)
NodeJS 中的代码:
async function paginate(query, offset, limit) {
let results;
if (offset > 0) {
// Get the keys (low cost)
query.select('__key__');
query.limit(offset + limit);
const [keys] = await datastore.runQuery(query);
const [entities] = await datastore.get(keys.slice(offset).map(k => k[Datastore.KEY]));
return entities;
}
query.limit(limit);
const [entities] = await datastore.runQuery(query);
return entities;
}