Datastore のクエリとは、指定した一連の条件を満たすエンティティを Cloud Datastore から取得する処理です。
一般的なクエリは次のような要素で構成されます。
クエリを実行すると、指定した種類のすべてのエンティティの中で指定したすべてのフィルタを満たすものが取得され、指定した順序で並べ替えられます。クエリは読み取り専用として実行されます。このページでは、Cloud Datastore からデータを取得するために App Engine で使用するクエリの構造と種類について説明します。
フィルタ
クエリのフィルタでは、取得するエンティティのプロパティ、キー、祖先に対する制約を設定します。
プロパティ フィルタ
プロパティ フィルタでは、次の要素を指定します。
- プロパティ名
- 比較演算子
- プロパティ値
プロパティ値はアプリケーションで提供する必要があります。他のプロパティを参照することも、他のプロパティを基準として計算することもできません。エンティティが指定された名前のプロパティを持ち、その値がフィルタで指定された値との比較演算子で示された条件に合致する場合、そのエンティティはフィルタを満たすものと見なされます。
比較演算子としては以下のいずれかを使用できます(ネストクラス
Query.FilterOperator
で列挙型定数として定義)。
演算子 | 意味 |
---|---|
EQUAL |
等しい |
LESS_THAN |
次の値より小さい |
LESS_THAN_OR_EQUAL |
次の値以下 |
GREATER_THAN |
次の値より大きい |
GREATER_THAN_OR_EQUAL |
次の値以上 |
NOT_EQUAL |
等しくない |
IN |
含まれる(指定されたリストのいずれかの値と等しい) |
NOT_EQUAL
演算子は、実際には 2 つのクエリを実行します。1 つは、その他のフィルタを変更することなく NOT_EQUAL
フィルタを LESS_THAN
に置換したクエリです。もう 1 つは、このフィルタを GREATER_THAN
に置換したクエリです。その後、それぞれの結果が適切な順序でマージされます。1 つのクエリに複数の NOT_EQUAL
フィルタを含めることはできません。また、このフィルタを含むクエリに別の不等式フィルタを含めることもできません。
同様に、IN
演算子も複数のクエリを実行します。その他のフィルタは変更することなく、IN
フィルタを EQUAL
フィルタに置換して、指定されたリストのアイテムごとにクエリを実行します。その後、それぞれの結果がリストのアイテムの順にマージされます。クエリに複数の IN
フィルタが含まれる場合は、IN
リスト内の値の可能な組み合わせごとにクエリが繰り返されます。
NOT_EQUAL
演算子または IN
演算子を含むクエリでは、サブクエリの数が 30 個以下に制限されます。
NOT_EQUAL
および IN
を含むクエリが JDO / JPA フレームワークで複数のクエリに変換される仕組みについては、!= および IN フィルタを使用したクエリをご覧ください。
主なフィルタ
エンティティのキーの値をフィルタリングするには、特殊なプロパティ Entity.KEY_RESERVED_PROPERTY
を使用します。
Entity.KEY_RESERVED_PROPERTY
に対する昇順の並べ替えもサポートされています。
異なる要素を比較する場合、キーは次の条件に従って次の順に順序付けられます。
- 祖先パス
- エンティティの種類
- 識別子(キー名または数値 ID)
祖先パスの各要素も同様に比較され、最初に種類(文字列)、次にキー名または数値 ID を基準として比較されます。種類とキー名は文字列であり、バイト値を基準として順序付けられます。また数値 ID は整数値であり、その数値の順に順序付けられます。同じ親と種類を持つエンティティが文字列のキー名と数値 ID を混用している場合、数値 ID を持つエンティティのほうがキー名を持つエンティティよりも優先されます。
キーを基準としたクエリではプロパティを基準としたクエリと同じようにインデックスを使用し、カスタム インデックスを必要とする場面も基本的に同じですが、いくつかの例外があります。キーに対して不等式フィルタを使用する場合、または昇順の並べ替え順を使用する場合はカスタム インデックスを必要としませんが、降順の並べ替え順を使用する場合は必要になります。すべてのクエリと同様に、開発用ウェブサーバーは、カスタム インデックスが必要なクエリをテストするときに、適切なエントリをインデックス構成ファイルに作成します。
祖先フィルタ
Datastore クエリは、指定した祖先でフィルタリングできます。これにより、返される結果には、その祖先の子孫のみが含まれるようになります。
特別なタイプのクエリ
特別なタイプのクエリについては、次の点に注意してください。
種類を指定しないクエリ
種類も祖先フィルタも指定していないクエリは、アプリケーションのすべてのエンティティを Datastore から取得します。これには、統計情報エンティティや Blobstore メタデータ エンティティなど、他の App Engine 機能によって作成、管理されるエンティティ(存在する場合)も含まれます。このような「種類を指定しないクエリ」では、プロパティ値に対するフィルタや並べ替え順序を含めることはできません。ただし、プロパティ名として Entity.KEY_RESERVED_PROPERTY
を指定することで、エンティティ キーによるフィルタリングが可能になります。
祖先クエリ
祖先フィルタを含むクエリの結果は、指定されたエンティティとその子孫に限定されます。
種類を指定しない祖先クエリ
祖先フィルタを含む「種類を指定しない」クエリは、種類にかかわりなく、指定した祖先と、その子孫のすべてを取得します。この種類のクエリにカスタム インデックスは必要ありません。すべての種類なしクエリと同様に、プロパティ値に対するフィルタや並べ替え順を含めることはできませんが、エンティティのキーに対するフィルタリングは可能です。
次の例は、特定の祖先を持つ子孫のエンティティをすべて取得する方法を示しています。
キーのみのクエリ
キーのみのクエリは、結果のエンティティ自体ではなく、エンティティのキーのみを返すため、エンティティ全体を取得するよりも、レイテンシとコストを抑えられます。
一般的なクエリを実行すると、実際に必要なものよりも多くのエンティティがフェッチされる場合があります。それに対して、まずキーのみのクエリを実行し、その結果からエンティティのサブセットをフェッチしたほうが、多くの場合経済的です。
射影クエリ
クエリの結果で実際に必要なのは、ごくわずかな特定のプロパティの値だけという場合もあります。このような場合、エンティティ全体を取得するのではなく、射影クエリを使用して実際に必要なプロパティだけを取得すると、レイテンシとコストを抑えることができます。詳細については、射影クエリをご覧ください。
並べ替え順序
クエリの並べ替え順序では、次の要素を指定します。
- プロパティ名
- 並べ替えの方向(昇順または降順)
例:
クエリに複数の並べ替え順序が含まれている場合は、指定されている順序で適用されます。次の例では、最初に名字の昇順で並べ替えてから、身長の降順で並べ替えます。
並べ替え順序が指定されていない場合、結果は Datastore から取得された順序で返されます。
注: あるプロパティに対して不等式フィルタを指定し、別のプロパティに対して並べ替え順序を指定する場合は、不等式フィルタで使用されているプロパティを他のプロパティよりも前に並べる必要があります。これは Datastore がクエリを実行する仕組みに原因があります。
インデックス
Datastore クエリでは、常に 1 つ以上のインデックスを使用して結果が計算されます。インデックスには、インデックスのプロパティとエンティティの祖先(省略可)によって指定されている順序でエンティティ キーが格納されています。インデックスは、アプリケーションがエンティティに加えた変更を反映して増分的に更新されます。そのため追加の計算を行うことなく、すべてのクエリの正しい結果が得られます。
App Engine は、エンティティの各プロパティに単純なインデックスを事前定義します。App Engine アプリケーションでは、アプリケーションの /war/WEB-INF/appengine-generated
ディレクトリに生成される datastore-indexes.xml
というインデックス構成ファイルで、さらにカスタム インデックスを定義できます。開発用サーバーは、既存のインデックスでは実行できないクエリが出現したときに、このファイルに自動的に候補を追加します。アプリケーションをアップロードする前にこのファイルを編集して、インデックスを手動で調整できます。
クエリ インターフェースの例
低レベルの Java Datastore API には、クエリを作成するためのクラス Query
と、Datastore からエンティティを取得するための PreparedQuery
インターフェースがあります。
FilterPredicate
と CompositeFilter
を使用してフィルタを作成していていることに注意してください。クエリに 1 つのフィルタのみを設定する場合は、FilterPredicate
を単独で使用できます。
ただし、クエリに複数のフィルタを設定する場合は、CompositeFilter
を使用する必要があります(これを使用するには 2 つ以上のフィルタが必要です)。上記の例では、CompositeFilterOperator.and
ショートカット ヘルパーを使用しています。次の例は、composite OR フィルタを作成する 1 つの方法を示しています。
次のステップ
- クエリが返す結果を指定する方法とクエリの結果を細かく制御する方法を学習します。
- Cloud Datastore でのクエリに関する一般的な制限について学習します。
- クエリの結果を一括して取得できるクエリカーソルについて学習します。
- データの整合性と、それが Cloud Datastore における異なるタイプのクエリでどのように動作するかを学習します。