代码之家  ›  专栏  ›  技术社区  ›  Zote

如何获取超过1000个?

  •  48
  • Zote  · 技术社区  · 16 年前

    16 回复  |  直到 8 年前
        1
  •  38
  •   Shay Erlichmen    14 年前

    从版本1.3.6(2010年8月17日发布)开始 可以

    From the changelog:

    datastore count()查询的结果 所有数据存储查询的偏移量不再限制在1000

        2
  •  23
  •   Tomasz Zieliński    14 年前

    仅就记录获取而言,1000条记录的限制现在已经取消:

    http://googleappengine.blogspot.com/2010/02/app-engine-sdk-131-including-major.html

    报价:

    右图:添加了游标和 许多较小的事件的高潮 数据存储稳定性和性能 我们现在有足够的信心移除 最大结果限制。 无论你是在抓取, 迭代,或使用游标,有

        3
  •  19
  •   JJ Geewax    14 年前

    AppEngine提供了一种很好的方法,通过对键进行排序,并使用最后一个键作为下一个偏移量,将结果“分页”1000次。他们甚至在这里提供了一些示例代码:

    http://code.google.com/appengine/docs/python/datastore/queriesandindexes.html#Queries_on_Keys

    尽管他们的示例将查询分散到多个请求上,但您可以将页面大小从20更改为1000,并将查询集组合在一起,以循环方式进行查询。此外,您可以使用itertools链接查询,而无需在需要查询之前对其进行评估。

    class MyModel(db.Expando):
        @classmethod
        def count_all(cls):
            """
            Count *all* of the rows (without maxing out at 1000)
            """
            count = 0
            query = cls.all().order('__key__')
    
            while count % 1000 == 0:
                current_count = query.count()
                if current_count == 0:
                    break
    
                count += current_count
    
                if current_count == 1000:
                    last_key = query.fetch(1, 999)[0].key()
                    query = query.filter('__key__ > ', last_key)
    
            return count
    
        4
  •  18
  •   Tony Arkles    16 年前

    为什么? 你需要1000条以上的结果吗?“你知道谷歌自己提供的结果不超过1000条吗?试试这个搜索: http://www.google.ca/search?hl=en&client=firefox-a&rls=org.mozilla:en-US:official&hs=qhu&q=1000+results&start=1000&sa=N

    如果您实际将1000多个结果返回给用户,那么我认为手头有一个比数据存储不允许您这样做更大的问题。

    需要这么多结果的一个可能(合理)原因是,如果您对数据进行了大型操作并提供了摘要(例如,所有这些数据的平均值是多少)。这个问题的解决方案(在GoogleI/O对话中讨论过)是动态计算汇总数据,并保存它。

        5
  •  14
  •   Kent Fredric    16 年前

    你不能。

    部分常见问题解答指出,您无法访问查询的第1000行以外的内容,增加“偏移量”只会导致结果集变短,

    来自维基百科:

    每个数据存储调用的行数。大多数网站 缓存,因此不需要这样做 一次有很多数据,所以这是一个 每次操作超过1000条记录 可以使用自己的客户端软件 或者一个Ajax页面来执行 对无限数量的 排。

    从…起 http://code.google.com/appengine/docs/whatisgoogleappengine.html

    返回的结果数 查询查询最多只能返回 返回更多结果只返回 最大限度在本例中,请求 执行这样的查询不太可能 在超时之前返回请求, 数据存储上的资源。

    从…起 http://code.google.com/appengine/docs/datastore/gqlreference.html

    GqlQuery类的fetch()方法。

    注意:与的偏移参数类似 查询字符串不会减少 性能特点 与偏移量线性对应 大小

    http://code.google.com/appengine/docs/datastore/queryclass.html

    限制和偏移量参数控件 从数据库中获取了多少个结果 数据存储,以及返回了多少

    • 数据存储向应用程序获取偏移量+限制结果。第一个偏移结果是

    • fetch()方法跳过第一个偏移量结果,然后返回其余结果(限制结果)。

    • 查询具有相应的性能特征 与偏移量加上限制成线性关系。

    如果您有一个单数查询,则无法请求0-1000范围之外的任何内容。

    增加偏移量只会增加0,因此

    LIMIT 1000  OFFSET 0    
    

    将返回1000行,

    LIMIT 1000 OFFSET 1000 
    

    0行

    是在表上创建数字索引,即:

     SELECT * FROM Foo  WHERE ID > 0 AND ID < 1000 
    
     SELECT * FROM Foo WHERE ID >= 1000 AND ID < 2000
    

    如果您的数据或查询不能具有此“ID”硬编码标识符,则您是

        6
  •  10
  •   BrettJ    8 年前

    这个1K限制问题已经解决。

    query = MyModel.all()
    for doc in query:
        print doc.title
    

    通过将查询对象视为iterable:迭代器以小批量从数据存储中检索结果,允许应用程序停止对结果进行迭代,以避免获取超出需要的结果。当检索到与查询匹配的所有结果时,迭代停止。与fetch()一样,迭代器接口不缓存结果,因此从查询对象创建新迭代器将重新执行查询。

    但是在plan 1.3.1 SDK中,他们引入了可以序列化和保存的游标,以便将来的调用可以从上次停止的地方开始查询。

        7
  •  7
  •   jakber    16 年前

    在谷歌AppEngine中,1000条记录的限制是一个硬限制。

    本演示文稿 http://sites.google.com/site/io/building-scalable-web-applications-with-google-app-engine 说明如何使用AppEngine高效地分页浏览数据。

        8
  •  6
  •   Tzach    10 年前

    当超过1000条记录时,尽管远程api仍存在获取问题。我们编写了这个小函数,以逐块遍历表:

    def _iterate_table(table, chunk_size = 200):
        offset = 0
        while True:
            results = table.all().order('__key__').fetch(chunk_size+1, offset = offset)
            if not results:
                break
            for result in results[:chunk_size]:
                yield result
            if len(results) < chunk_size+1:
                break
            offset += chunk_size
    
        9
  •  3
  •   Gabriel    14 年前

    ModelBase

    @classmethod
    def get_all(cls):
      q = cls.all()
      holder = q.fetch(1000)
      result = holder
      while len(holder) == 1000:
        holder = q.with_cursor(q.cursor()).fetch(1000)
        result += holder
      return result
    

        10
  •  2
  •   fun_vit    15 年前
    class Count(object):
    def getCount(self,cls):
        class Count(object):
    def getCount(self,cls):
        """
        Count *all* of the rows (without maxing out at 1000)
        """
        count = 0
        query = cls.all().order('__key__')
    
    
        while 1:
            current_count = query.count()
            count += current_count
            if current_count == 0:
                break
    
            last_key = query.fetch(1, current_count-1)[0].key()
            query = query.filter('__key__ > ', last_key)
    
        return count
    
        11
  •  2
  •   cfern    13 年前
    entities = []
    for entity in Entity.all():
        entities.append(entity)
    

    就这么简单。请注意,每个实体都有一个RPC,它比在块中获取要慢得多。因此,如果您关心性能,请执行以下操作:

    如果您的物品少于100万件:

    entities = Entity.all().fetch(999999)
    

    否则,请使用光标。

    Entity.all().fetch(Entity.all().count())
    

        12
  •  1
  •   mhawthorne    15 年前

    JJG:您上面的解决方案非常棒,只是如果您有0条记录,它会导致无限循环。(我在本地测试我的一些报告时发现了这一点)。

    while count % 1000 == 0:
        current_count = query.count()
        if current_count == 0:
            break
    
        13
  •  0
  •   Tom Leys    16 年前

    list1 = first query
    list2 = second query
    list1 += list2
    

    列表1现在包含所有2000个结果。

        14
  •  0
  •   cjed cjed    15 年前

    仅当条目按键排序时,建议的解决方案才有效。。。如果您先按另一列排序,您仍然必须使用limit(offset,count)子句,那么1000个条目的限制仍然适用。如果使用两个请求也是一样的:一个用于检索索引(带有条件和排序),另一个使用where index in()以及第一个结果的索引子集,因为第一个请求返回的键不能超过1000个?(谷歌 查询钥匙 钥匙 取消1000个结果限制)

        15
  •  0
  •   Timothy Tripp    13 年前

    这与Gabriel提供的解决方案非常接近,但无法获取结果,而只是计算结果:

    count = 0
    q = YourEntityClass.all().filter('myval = ', 2)
    countBatch = q.count()
    while countBatch > 0:
        count += countBatch
        countBatch = q.with_cursor(q.cursor()).count()
    
    logging.info('Count=%d' % count)
    

    请注意,查询不能是不等式过滤器或集合,否则光标将不起作用,您将得到以下异常:

    AssertionError:没有可用于多重查询的游标(使用“IN”或“!=”运算符的查询)

        16
  •  0
  •   Oded Breiner    8 年前

    如果您正在使用NDB:

    @staticmethod
    def _iterate_table(table, chunk_size=200):
        offset = 0
        while True:
            results = table.query().order(table.key).fetch(chunk_size + 1, offset=offset)
            if not results:
                break
            for result in results[:chunk_size]:
                yield result
            if len(results) < chunk_size + 1:
                break
            offset += chunk_size