私の Google App Engine アプリでは、サービス呼び出しの GET リクエストに応答して、データストア クエリから潜在的に多数のエンティティを取得して返す必要があります。この呼び出しは、潜在的に数千のエンティティと MB のシリアル化されたデータを返す可能性があります。
応答パケットの最初の部分は、シリアル化された結果に含まれるエンティティの数を伝え、その後にすべてのシリアル化されたエンティティが続きます。現在、クエリ内のすべてのエンティティをQueryResultIterator
最大ページ サイズ制限まで反復処理しています。その後、カーソルを返します。このカーソルを使用して、前の呼び出しが中断された場所からフェッチを続行できます (最大値に達し、それでもクエリが返されます)。結果を反復処理しながら、それらをリストに保存します。クエリ結果を使い果たすか、最大ページ サイズに達すると、このリストのサイズからエンティティの数を取得できます。しかし、このリストをもう一度反復処理して各エンティティをシリアル化し、結果を応答出力ストリームに書き込む必要があります。
これがこの操作を実行する最も効率的な方法かどうかはわかりません。実際にすべてを反復処理するか、リストに直接フェッチする前に、クエリの結果のエンティティの数を取得する方法はありますか? (リストメソッドはとにかく機能しません。これは、QueryResultIterator を使用する必要があるカーソルを使用しているためです)。
QueryResultIterator
メソッドがありgetIndexList()
ます。これは、クエリの結果に含まれるエンティティの数を取得するための低コストの方法でしょうか? このリストには、クエリの結果のエンティティごとに正確に 1 つのインデックス オブジェクトが含まれると想定しています。また、このリストには、インタレータの現在のカーソル位置の後のエンティティのインデックスのみを含める必要があります。私の理解は正しいですか、それともこの方法は私が思っていることをしませんか?
インデックスだけのリストは、エンティティ全体のリストをロードするよりもはるかに少ないメモリを必要とします。ただし、このリストがクエリのプリフェッチまたはチャンク サイズによってまったく制限されるかどうか、またはクエリの limit パラメータを使用する必要があるかどうかはわかりません。最大ページ サイズに 1 を加えたサイズまでの結果 (まだ結果があることを知り、続行するためのカーソルを提供するため)。
現在、プリフェッチとチャンク サイズを (ページ制限のサイズに) 設定していますが、代わりにカーソルを使用しているため、制限またはオフセット パラメータは使用していません。私が理解していることから、カーソルはオフセット/制限よりも望ましいです。limit パラメーターを設定すると、カーソルを使用したクエリの続行に影響しますか?
明らかに、GAE データストア クエリがどのように機能し、パラメータの変更によってどのように影響を受けるかについて、かなりの数の質問があります。したがって、どんな洞察も高く評価されます。App Engine API のドキュメントは、多くの場合、メソッド シグネチャから推測できるほとんどの内容をメソッドの 1 つの文で説明しているように、まばらです。それ以外の場合は、通常、あまり詳細には触れません。結局、今のやり方でいいのかもしれません。そのままで動作しますが、サービス呼び出しを最適化して、クライアント アプリケーションで可能な限り最高の応答時間を取得しようとしています。
更新:ところで、私は自分のアプリでObjectify v3 を使用しており、このクエリを実行しています。地理位置クエリ ( geomodelを使用) や投影クエリ (Objectify v3 ではサポートされていません) を実行するなど、低レベルのデータストア API を使用する必要がある場所がいくつかあります。したがって、Objectify を使用してこれを行う良い方法があれば、それが理想的です。それ以外の場合は、低レベル API を使用できますが、この方法では常に面倒です。