Google app engine 是否使用批处理查询分页?是否可以从数据存储中批量获取并获取游标?

Google app engine 是否使用批处理查询分页?是否可以从数据存储中批量获取并获取游标?,google-app-engine,go,google-cloud-datastore,Google App Engine,Go,Google Cloud Datastore,我目前正在从数据存储中请求20个条目,使用光标将这些条目返回给用户,如果用户请求更多条目,请使用光标作为新的开始,并请求接下来的20个条目 代码看起来像 q := datastore.NewQuery("Item"). Limit(limit) if cursor, err := datastore.DecodeCursor(cursor); err == nil { q = q.Start(cursor) } var is []Item t := q.Run(c) for

我目前正在从数据存储中请求20个条目,使用光标将这些条目返回给用户,如果用户请求更多条目,请使用光标作为新的开始,并请求接下来的20个条目

代码看起来像

q := datastore.NewQuery("Item").
    Limit(limit)

if cursor, err := datastore.DecodeCursor(cursor); err == nil {
    q = q.Start(cursor)
}

var is []Item
t := q.Run(c)
for {
    var i Item
    _, err := t.Next(&i)
    if err == datastore.Done {
        break
    }

    is = append(is, i)
}
如果很重要,这里有完整的代码:

使用带有
append
的循环看起来是一种反模式,但在使用
GetMulti
/
GetAll
时,我看不到一种获取光标的方法,或者我遗漏了什么


我确实希望在用户查询数据存储时添加数据,因此偏移量可能会产生重复的结果。在这种情况下,我应该关心批处理吗?

您的方法非常好,事实上,这是AppEngine上最好的方法

例如,如果插入了第一条新记录,则通过设置开始游标查询后续实体不会得到重复的结果

为什么??因为光标包含编码的最后一个返回实体的键,而不是先前返回的实体数

因此,如果设置游标,数据存储将开始列出并返回游标中编码的键之后的实体。如果保存光标后的新实体,则到达时将返回该实体

另外,使用
for
append()
也是最好的方法。您可以通过事先创建足够大的切片来对其进行一些优化:

var is = make([]Item, 0, limit)
但请注意,我故意使用
0
长度和
限制
容量:无法保证有足够的实体填充整个切片

另一个优化是将其分配为
限制
长度:

var is = make([]Item, limit)
当到达
datastore.Done
时,如果未完全填充,则重新许可,例如:

for idx := 0; ; idx++ {
    var i Item
    _, err := t.Next(&i)
    if err == datastore.Done {
        if idx < len(is) {
            is = is[:idx] // Reslice as it is not filled fully
        }
        break
    }

    is[idx] = i
}
对于idx:=0;
;idx++{
var i项目
_,err:=t.Next(&i)
如果err==datastore.Done{
如果idx
批处理操作
GetMulti
PutMulti
DeleteMulti
Get
Put
Delete
函数的批处理版本。它们使用
[]*键
而不是
*键
,当遇到部分故障时,可能会返回
appengine.MultiError

批处理操作不是查询的替代或替代<例如,code>GetMulti
要求您已经准备好要获取完整实体的所有键。因此,这些批处理操作没有光标的感觉

批处理操作将返回所有请求的信息(或执行所有请求的操作)。没有将/可能终止并在以后继续的实体或业务序列


查询和批处理操作用于不同的事情。您不应该担心查询和游标的性能。它们做得很好,重要的是,它们(数据存储)的扩展性很好。游标不会减慢查询的执行速度,带游标的查询的运行速度与不带游标的查询的运行速度一样快,而且以前返回的实体不会影响查询执行时间:无论您是在不带游标的情况下运行查询,还是在获得一百万个实体后使用游标运行查询(只有经过多次迭代才可能实现)。

感谢您的详细解释。您还可以对数据存储访问效率发表意见吗?我是否应该期望与批处理访问相比有所不同?@jens批处理操作和查询不是相互替代的。请参阅编辑的答案。