【问题标题】:Google App Engine - getting count of records that match criteria over 1000Google App Engine - 获取符合条件的记录数超过 1000
【发布时间】:2011-04-17 11:50:37
【问题描述】:

我在多个位置读到 GAE 取消了对查询和计数的 1000 条记录限制,但是,我似乎只能获得最多 1000 条记录的计数。我不会拉超过 1000 条查询一次,但要求是我需要对匹配记录进行计数。

我知道您可以使用游标对数据集进行“分页”,但为了获得计数而循环浏览似乎有点多。据推测,当他们说他们“取消”了限制时,这是硬限制 - 你仍然需要一次循环查看 1000 个结果,对吗?

我应该使用 .all()/filter 方法以外的方法来生成 1000+ 个计数吗?

提前感谢您的帮助!

【问题讨论】:

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


    【解决方案1】:

    当没有明确指定限制时,Query.count() 的行为与文档不一致 - 文档表明它将计数“直到它完成计数或超时”。 GAE Issue 3671 报告了这个错误(大约 3 周前)。

    解决方法:明确指定一个限制,然后将使用该值(而不是默认值 1,000)。

    http://shell.appspot.com 上的测试证明了这一点:

    # insert 1500 TestModel entites ...
    # ...
    >>> TestModel.all(keys_only=True).count()
    1000L
    >>> TestModel.all(keys_only=True).count(10000)
    1500L
    

    我还在使用这个简单的测试应用程序的最新版本的开发服务器 (1.3.7) 上看到了相同的行为:

    from google.appengine.ext import webapp, db
    from google.appengine.ext.webapp.util import run_wsgi_app
    
    class Blah(db.Model): pass
    
    class MainPage(webapp.RequestHandler):
        def get(self):
            for i in xrange(3):
                db.put([Blah() for i in xrange(500)])  # can only put 500 at a time ...
            c = Blah.all().count()
            c10k = Blah.all().count(10000)
            self.response.out.write('%d %d' % (c,c10k))
            # prints "1000 1500" on its first run
    
    application = webapp.WSGIApplication([('/', MainPage)])
    
    def main(): run_wsgi_app(application)
    if __name__ == '__main__': main()
    

    【讨论】:

    • 我会试试你的解决方案,看看我能走多远。您必须为计数提供限制的想法显然是荒谬的,但希望它会很快得到解决。谢谢!
    • 这并不荒谬——数数需要花费 O(n) 时间,而且大概你愿意花多少时间数数有一个上限?
    • 这很奇怪!? (p.s. 你的第二个例子不能工作,因为批处理限制为 500)
    • @systempuntoout 好点。不幸的是,开发服务器确实允许批量放置 >500 个实体(与生产服务器不同)。我已经调整了代码,使其也可以在生产服务器上“工作”。
    【解决方案2】:

    根据此App Engine blog post,仅在版本 1.3.6 中删除了 count(和 offset)的 1000 个实体限制。自版本 1.3.1 起,fetch 的限制已被删除。升级到最新版本,应该会取消限制。

    您不需要一次循环浏览 1000 个结果(尽管您可以这样做,而且效率可能更高);只需传入您想要返回的最大结果数:

        for m in MyModel.all().fetch(82000):
            # ...
    

    在 1.3.1 之前的版本中,传入的数字必须小于或等于 1000。

    【讨论】:

    • 理想的解决方案是升级到最新版本。不幸的是,最新版本中有一个错误导致文档与行为不一致 - count() 将仅返回 1,000 个结果,除非您明确提供大于 1,000 的限制。
    • 正如 Underhill 先生所说,无论出于何种原因,错误或其他原因,即使使用最新版本,对查询的简单计数也只会产生 1000。
    【解决方案3】:

    Issue 3671 中建议的那样,如果您想计算所有记录,您可以将限制设置为无(而不是高于 1000 的数字,这仍然有助于限制计数),尽管不建议这样做并且而是对事务中的计数进行非规范化。

    total_records = query.count(limit=None)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-10
      相关资源
      最近更新 更多