Google app engine 是否使用批处理查询分页?是否可以从数据存储中批量获取并获取游标?
我目前正在从数据存储中请求20个条目,使用光标将这些条目返回给用户,如果用户请求更多条目,请使用光标作为新的开始,并请求接下来的20个条目 代码看起来像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
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批处理操作和查询不是相互替代的。请参阅编辑的答案。