Jef*_*art 1 java google-app-engine objectify
在我的Google App Engine应用程序中,我需要从数据存储区查询中获取并返回可能大量的实体,以响应服务调用GET请求.此调用可能返回数千个实体和MB的序列化数据.
响应数据包的第一部分传达序列化结果中有多少实体,然后是所有序列化实体.目前我正在迭代查询中的所有实体,QueryResultIterator最大页面大小限制,之后我返回一个光标,从中可以用来继续获取前一个调用停止的位置(如果达到最大值并且有仍导致查询).当我遍历结果时,我将它们保存在列表中.一旦我用尽了查询结果或达到最大页面大小,我就可以从该列表的大小中获取实体数量.但是我必须再次遍历此列表以序列化每个实体并将结果写入响应输出流.
我不知道这是执行此操作的最有效方法.有没有一种方法可以在实际迭代查询结果或直接将它们提取到列表中之前获取查询结果中的实体数量?(列表方法无论如何都不起作用,因为我正在使用游标,这需要使用QueryResultIterator).
QueryResultIterator有一个方法getIndexList().这是获得查询结果中实体数量的成本较低的方法吗?我假设此列表将包含查询结果中每个实体的一个索引对象.此外,我需要此列表仅包含在交互器的当前光标位置之后的实体的索引.我的理解是正确的还是这种方法不会做我想的那样?
仅加载索引的列表将比加载整个实体的列表需要更少的内存.虽然,我不知道这个列表是否会受到查询的预取或块大小的限制,或者我是否想要使用查询的limit参数,因为我只想知道有多少实体在结果最大页面大小加一(知道还有更多结果并提供光标继续).
目前我正在设置预取和块大小(到我的页面限制的大小),但我没有使用限制或偏移参数,因为我正在使用游标.根据我的理解,游标优于偏移/限制.设置limit参数是否会影响使用游标继续查询?
很明显,我有很多关于GAE数据存储查询如何工作以及它们如何受到更改参数影响的问题.所以任何见解都表示赞赏.App Engine API的文档通常很少,因为在一个句子中描述的方法几乎说明了可以从方法签名中推断出什么.否则他们通常不会详细说明.也许我现在这样做的方式毕竟还不错.它按原样工作,但我正在尝试优化服务调用,以便为我的客户端应用程序获得最佳响应时间.
更新:顺便说一句,我在我的应用程序中使用Objectify v3并执行此查询.我需要使用低级数据存储API的几个地方,包括进行地理位置查询(使用geomodel)和投影查询(在Objectify v3中不支持).因此,如果使用Objectify有一个很好的方法,那将是理想的.否则我可以使用低级API,但这种方式总是比较麻烦.
低级api和Objectify都有一个count()方法(详见javadocs).但是,计数可能是一个非常昂贵和冗长的操作 - 每返回一个数字需要1个小操作.例如,count()返回5000会花费5000个小操作(加上查询的1个读取),并且需要花费足够长的时间来执行所有5000的仅按键扫描(这是GAE实际上做的).
如果你绝对必须有一个确切的计数,你可能需要通过递增/递减(可能是分片的)计数器来自己聚合这个值.当您处理过滤后的查询时,这会变得非常棘手.
这里没有一个正确的解决方案.Google搜索会为您提供"约119,000,000个结果"等总计,这些结果是故意不准确且几乎肯定是预先计算的.对于较小的结果集,使用count()是可以接受的 - 但是您可能希望应用limit()以便永远不会破坏银行.你总是可以说"超过500个结果......"
| 归档时间: |
|
| 查看次数: |
1462 次 |
| 最近记录: |