クエリカーソル

クエリカーソルを使用すると、アプリケーションでクエリの結果を一括して取得できます。ページ処理には整数オフセットを使うよりもクエリカーソルを使うことをおすすめします。アプリでのクエリの構成方法について詳しくは、クエリをご覧ください。

クエリカーソル

クエリカーソルを使用すると、クエリ オフセットのオーバーヘッドを発生させることなく、アプリケーションでクエリの結果を一括して取得できます。取得オペレーションを実行した後、アプリケーションはカーソルを取得できます。カーソルは Base64 でエンコードされた不透明な文字列で、最後に結果が取得されたインデックス位置をマーク付けします。アプリケーションはこの文字列を保存し(たとえば、Google Cloud Datastore、Memcache、タスクキューのタスク ペイロードなどに保存するか、HTTP の GET パラメータまたは POST パラメータとしてウェブページに埋め込む)、後続の取得オペレーションの開始点としてカーソルを使用できます。これにより、前の取得オペレーションが終了した位置から次の結果のバッチを取得できます。取得オペレーションでは終了カーソルも指定できるため、返される結果セットの範囲を制限できます。

オフセットとカーソル

Cloud Datastore では整数のオフセットをサポートしていますが、使用は避けてください。その代わりにカーソルを使用します。オフセットを使用するとスキップされたエンティティがアプリケーションに返されなくなりますが、そのようなエンティティも内部的には引き続き取得されています。スキップされたエンティティはクエリのレイテンシに影響するだけでなく、そのようなエンティティの取得に必要な読み取りオペレーションに対してアプリケーションが課金されます。このようなコストは、オフセットの代わりにカーソルを使用することですべて回避できます。

クエリカーソルの例

Python では、アプリケーションがクエリ結果の取得後に Query オブジェクトの cursor() メソッドを呼び出すことによってカーソルを取得します。カーソル位置以降の結果を取得するには、アプリケーションで、エンティティの種類、フィルタ、並べ替え順序が同じである類似クエリを作成し、取得の実行前にカーソルをクエリの with_cursor() メソッドに渡します。

from google.appengine.api import memcache
from google.appengine.ext import db

# class Person(db.Model): ...

# Start a query for all Person entities
people = Person.all()

# If the application stored a cursor during a previous request, use it
person_cursor = memcache.get('person_cursor')
if person_cursor:
  people.with_cursor(start_cursor=person_cursor)

# Iterate over the results
for person in people:
  # Do something

# Get updated cursor and store it for next time
person_cursor = people.cursor()
memcache.set('person_cursor', person_cursor)

カーソルの制限

カーソルには次のような制限があります。

  • カーソルを使用できるのは元のクエリを実行したアプリケーションと同じアプリケーションだけであり、同じクエリに対してのみ継続します。後続の取得オペレーションでカーソルを使用するには、エンティティの種類、祖先フィルタ、プロパティ フィルタ、並べ替え順序を同じにするなど、元のクエリを正確に再作成する必要があります。元の生成元から同じクエリを設定しない限り、カーソルを使用して結果を取得することはできません。
  • != 演算子と IN 演算子は複数のクエリで実装されるため、これらの演算子を使用するクエリはカーソルをサポートしません。
  • 複数の値を持つプロパティに対して不等式フィルタまたは並べ替え順序を使用するクエリでは、カーソルが常に予期したとおりに動作するとは限りません。このような複数の値を持つプロパティに対する重複排除ロジックは取得オペレーション間で保持されないため、同じ結果が複数回返される原因となる場合があります。
  • App Engine の新しいリリースでは内部実装の詳細が変更される場合があり、それに依存するカーソルは無効になる可能性があります。有効ではなくなったカーソルをアプリケーションで使用しようとすると、Cloud Datastore で BadRequestError 例外が発生します。

カーソルとデータ更新

カーソルの位置は、最後の結果が返された後の結果リスト内の位置として定義されます。カーソルはリスト内の相対的な位置ではありません(オフセットではありません)。結果に対するインデックス スキャンを開始したときに Cloud Datastore がジャンプできる位置を示すマーカーです。以前のカーソル使用時からクエリの結果が変更されている場合、クエリが認識するのは、そのカーソル位置よりも後の結果で発生した変化だけです。新しい結果の位置がクエリのカーソル位置よりも前の場合、カーソルより後の結果をフェッチしても、その新しい結果は返されません。同様に、あるエンティティがクエリの結果ではなくなったものの、カーソルよりも前の位置に存在していた場合、カーソルよりも後の位置の結果は変化しません。また最後に返された結果が結果セットから削除された場合でも、その次の結果の位置は引き続きカーソルで特定できます。

クエリの結果を取得するときは、開始カーソルと終了カーソルの両方を使用することで、連続した結果のグループを Cloud Datastore から返せます。開始カーソルと終了カーソルを使用して結果を取得する場合、結果セットのサイズがカーソル生成時と同じであることは保証されません。これはカーソル生成時からクエリでの使用時までの間に、Cloud Datastore でエンティティの追加または削除が実行される可能性があるためです。

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Python の App Engine スタンダード環境