当前位置: 首页 > 面试题库 >

分页与批处理查询?是否可以从数据存储中批处理获取并获取游标?

呼延德华
2023-03-14
问题内容

我目前正在从数据存储区中请求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)
}

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

使用带有的循环看起来像是反模式append,但是使用GetMulti/ GetAll时我看不到获取光标的方法,或者我错过了什么吗?

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


问题答案:

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

如果插入了一条新记录(例如第一个记录),则通过设置开始光标来查询后续实体不会给您重复的结果。

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

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

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

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

但是请注意,我故意这样做是出于0长度和limit容量的考虑:不能保证会有足够的实体来填充整个切片。

另一个优化是将其分配为limitlength:

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
}

批量操作

GetMultiPutMulti并且DeleteMulti是的批量版本GetPutDelete功能。它们采用[]*Key而不是*Key,并且appengine.MultiError在遇到部分故障时可能会返回。

批处理操作不是查询的替代或替代。GetMulti例如,要求您已经准备好要获取完整实体的所有键。因此,这些批处理操作没有任何游标意义。

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

查询和批处理操作是针对不同的事物的。您不必担心查询和游标的性能。它们做得很好,而且重要的是,它们(数据存储区)可扩展。游标不会降低查询的执行速度,带游标的查询的运行速度与没有游标的查询一样快,并且先前返回的实体也不会影响查询的执行时间:是否运行查询都没有关系没有游标或拥有一百万个实体后获得的游标(只能通过多次迭代获得)。



 类似资料:
  • 如果我的平面文件中有不正确数量的令牌,我会遇到以下异常。 如果我抓住了错误的标记异常我想打印自定义错误日志与文件名,行号和行引起异常。 帮助我。 非常感谢。

  • 我正在使用一个相当大的数据集(大约500Mio-Triples)存储在图形数据库免费并在我的本地开发人员机器上运行。 我想用RDF4J对数据集执行一些操作,并且必须或多或少地选择整个数据集。要进行测试,我只需选择所需的元组。代码在第一个一百万元组中运行良好,之后由于graphDB继续分配更多的RAM,速度变得非常慢。 是否有可能对非常大的数据集执行选择查询并批量获取它们? 基本上,我只想通过一些选

  • 嗨,我是新春批。 我有如下Spring批次的情况: 我需要运行所有促销的批处理[促销列表] > 在这里,我想再次从batch中读取上面的动态查询,因为它返回的结果至少为5万条记录。 以下是我所期待的过程,这在Spring批次中是否可行? 阅读促销【读者逐一阅读促销】 创建查询并将其放在上下文中 传递给下一个读者 读取器逐个读取事务 处理交易并计算积分 我这里的问题是不能写嵌套块[一个用于读取提升,

  • 问题内容: 我正在尝试从下面给出的Java版本输出中获取‘6’ 同样,我写了这个批处理脚本 显示“ 1.6.0_21” 有人可以指导我正确的方向吗?我不太熟悉。 问题答案: 在第一个循环中,说我们将仅使用命令输出中的第三个标记。无需将命令的输出重定向到文件,我们可以在循环本身中运行此命令。插入记号()是转义字符,并且需要,所以我们可以嵌入,并在命令字符串符号。 在循环体内,我们设置了一个新的var

  • 我想为spring批处理使用不同的数据源,并创建了下面的配置类,并根据文档将我所需的数据源自动连接到该类。 我使用的是spring boot(2.2.6)和spring batch版本4.2.1。释放 但当我用它启动应用程序时,它从不应用setTablePrefix,并且总是会失败,出现table not found错误。 我需要使用上面的方法,因为我有两个不同的数据源,我需要spring批处理来

  • 当我使用Spring批处理管理运行长时间运行的批处理作业的多个实例时,它会在达到jobLauncher线程池任务执行程序池大小后阻止其他作业运行。但是从cron中提取多个工作似乎效果不错。下面是作业启动器配置。 Spring批处理管理员Restful API是否使用不同于xml配置中指定的作业启动器?