4

Google データストア内の 10 万以上のエンティティの場合、ndb.query().count() は、インデックスを使用しても、deadline までにキャンセルされます。私は Produce_cursors オプションを試しましたが、iter() または fetch_page() のみがカーソルを返しますが、count() は返しません。

大きなエンティティをカウントするにはどうすればよいですか?

4

3 に答える 3

2

高価なことをするには、Task Queue Python APIを見てください。Task Queue API に基づいて、Google App Engine はdeferred ライブラリを提供します。これを使用して、バックグラウンド タスクの実行プロセス全体を簡素化できます。

アプリで遅延ライブラリを使用する方法の例を次に示します。

import logging

def count_large_query(query):
  total = query.count()
  logging.info('Total entities: %d' % total)

次に、アプリ内から上記の関数を次のように呼び出すことができます。

from google.appengine.ext import deferred

# Somewhere in your request:
deferred.defer(count_large_query, ndb.query())

count()このような大規模なデータストアで結果が返されるかどうかはまだわかりませんがcount_large_query()、代わりにカーソルを使用するこの関数を使用できます (未テスト):

LIMIT = 1024
def count_large_query(query):
  cursor = None
  more = True
  total = 0
  while more:
    ndbs, cursor, more = query.fetch_page(LIMIT, start_cursor=cursor, keys_only=True)
    total += len(ndbs)

  logging.info('Total entitites: %d' % total)

上記をローカルで試すには、LIMITを 4 に設定し、コンソールに行が表示されるかどうかを確認しますTotal entitites: ##


Guido がコメントで述べたように、これもスケーリングされません。

これはまだスケーリングしません (問題を先延ばしにする可能性はありますが)。タスクは 1 分ではなく 10 分なので、10 倍の数のエンティティを数えることができます。しかし、それはかなり高価です!これを適切に解決したい場合は、シャードされたカウンターを検索してください (残念ながら、それは大変な作業です)。

そのため、スケーラブルなアプリケーション、特にシャーディング カウンターを作成するためのベスト プラクティスを確認することをお勧めします。

于 2013-02-04T11:39:29.240 に答える
2

これは実に悩ましい問題です。最近、この分野でいくつかの作業を行って、一般的なカウント統計を取得しています。基本的には、クエリを満たすエンティティの数です。count()これは素晴らしいアイデアですが、データストアの RPC タイムアウトによって妨げられています。

count()キーの大きなリストを返すだけでそれらを捨てるのではなく、結果セット全体にカーソルを合わせて、結果の整数を単純に合計できるように、カーソルが何らかの形でサポートされていると便利です。カーソルを使用すると、「バトンを渡す」遅延アプローチを使用して、すべての 1 分 / 10 分の境界を越えて続行できます。count()( とは対照的に) を使用fetch(keys_only=True)すると、浪費を大幅に削減でき、できれば RPC 呼び出しの速度を向上させることができます。たとえば、このfetch(keys_only=True)アプローチを使用すると 1,000,000 までカウントするのに驚くほどの時間がかかります。

定期的なカウント統計 (たとえば、国ごとのシステム内のすべてのアカウントの毎日のカウントなど) のみが必要な場合、または必要な場合、シャードされたカウンターは多くのオーバーヘッドになります。

于 2013-02-05T17:18:19.493 に答える
1

Google App Engine バックエンドを使用することをお勧めします。バックエンドは、ユーザー リクエストの 60 秒の期限とタスクの 10 分の期限から免除され、無期限に実行されます。こちらのドキュメントをご覧ください: https://developers.google.com/appengine/docs/java/backends/overview

于 2013-02-04T03:02:45.867 に答える