分批查询的分页?是否可以从数据存储区批量获取并获取游标?

时间:2015-08-09 09:46:55

标签: google-app-engine go google-cloud-datastore

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

代码看起来像

import pandas as pd
import numpy as np

# sample datetime index
# ================================
ts_index = pd.date_range(start='20140101', end='20140501', freq='M')
ts_index

DatetimeIndex(['2014-01-31', '2014-02-28', '2014-03-31', '2014-04-30'], dtype='datetime64[ns]', freq='M', tz=None)

# processing
# ===================================
ts_index.values.astype('<M8[M]').astype(str)

array(['2014-01', '2014-02', '2014-03', '2014-04'], 
      dtype='<U25')

如果重要的话,这里是完整的代码:https://github.com/koffeinsource/kaffeeshare/blob/master/data/appengine.go#L23

使用带有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或上午时,我看不到获取光标的方法我错过了什么?

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

1 个答案:

答案 0 :(得分:1)

你的方法非常好,事实上,它是AppEngine的最佳方式。

通过设置开始游标来查询后续实体,如果插入的新记录是第一个,则不会给出重复的结果。

为什么呢?因为游标包含最后返回的实体的密钥编码,而不是先前返回的实体的数量。

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

同样使用forappend()是最好的方法。您可以通过事先创建一个足够大的切片来优化它:

var is = make([]Item, 0, limit)

但请注意,我故意使用0长度和limit容量:无法保证有足够的实体来填充整个切片。

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

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
}

批处理操作

  

GetMultiPutMultiDeleteMultiGetPutDelete函数的批量版本。他们使用[]*Key代替*Key,并在遇到部分失败时返回appengine.MultiError

批处理操作不是查询的替代或替代。例如,GetMulti要求您已准备好要为其获取完整实体的所有密钥。因此,对这些批处理操作没有任何感觉。

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

查询和批处理操作适用于不同的事情。您不应该担心查询和游标性能。他们做得很好,重要的是,他们(数据存储区)规模很好。游标不会减慢查询的执行速度,带有游标的查询将像没有游标的查询一样快地运行,并且先前返回的实体也不会影响查询执行时间:如果运行查询则无关紧要没有光标或者在获得一百万个实体后获得的光标(只能进行多次迭代)。