クエリの制限

このページでは、Google App Engine から Google Cloud Datastore に行うクエリに関する制限について説明します。次のリストは、Cloud Datastore 向けの開発時に課される一般的な制限です。

クエリでプロパティが指定されていないエンティティは無視される

同じ種類のエンティティが同じプロパティを持つとは限りません。エンティティがクエリ結果の対象になるためには、クエリのフィルタと並べ替え順序で指定されているすべてのプロパティについて値(場合によっては null)を持っていなければなりません。そうでない場合、そのエンティティはクエリの実行に使用されているインデックスから除外され、クエリの結果には含まれなくなります。

インデックス付けされていないプロパティに対するフィルタリングからは結果が返されない

クエリはインデックス付けされていないプロパティ値を見つけられず、そのようなプロパティを並べ替えることもできません。インデックス付けされていないプロパティの詳しい説明については、データストア インデックス ページをご覧ください。

不等式フィルタの対象は最大で 1 つのプロパティに制限される

インデックス全体をスキャンしなくても済むように、クエリ メカニズムでは、潜在的なクエリの結果がすべてインデックス内で互いに隣接していることが求められます。この制約を満たすため、単一クエリは、そのフィルタのすべてで複数のプロパティに対して不等比較(<<=>>=!=)を使用できません。たとえば次のクエリは、どちらの不等式フィルタも同じプロパティに適用されているため有効です。

SELECT * FROM Person WHERE birth_year >= :min_birth_year
                       AND birth_year <= :max_birth_year

ただし次のクエリは 2 種類のプロパティに対して不等式フィルタを使用しているため無効です。

SELECT * FROM Person WHERE birth_year >= :max_birth_year
                       AND height <= :max_height          # ERROR

クエリでは、単一のプロパティに対する 1 つ以上の不等式フィルタと、複数のプロパティに対する等式(=)フィルタを組み合わせることが可能です。そのため、次のクエリは有効です。

SELECT * FROM Person WHERE last_name = :target_last_name
                       AND city = :target_city
                       AND birth_year >= :min_birth_year
                       AND birth_year <= :max_birth_year

並べ替え順序が指定されていない場合、クエリ結果の順序付けは定義されない

クエリで並べ替え順序を指定していない場合、結果は取得された順序で返されます。この順序は、Cloud Datastore 実装の進展(またはアプリケーションのインデックスの変更)に伴って変化する可能性があります。そのため、クエリの結果が特定の順序に並べ替えられている必要があるアプリケーションでは、並べ替え順序をクエリで明示的に指定してください。

等式フィルタが使用されたプロパティでは並べ替え順序が無視される

特定のプロパティに対して等式フィルタが使われているクエリでは、そのプロパティに対するいかなる並べ替え順序も無視されます。そのプロパティについては、すべての結果で同じ値になるため、それ以上の並べ替えは不要です。そのためこれは、単一値のプロパティに対する不要な処理を節減するためのシンプルな最適化といえます。ただし複数の値を持つプロパティは、等式フィルタに一致したもの以外にも値を持つ可能性があります。このユースケースはまれであり、並べ替え順序を適用するとコストがかかり、余分なインデックスが必要となるため、Cloud Datastore のクエリ プランナーでは複数の値を持つ場合であっても単純に並べ替え順序を無視しています。これは、プロパティの値から連想される順序とは異なる順序でクエリの結果が返される原因となる可能性があります。

不等式フィルタで使われているプロパティは最初に並べ替える必要がある

不等式フィルタに一致するすべての結果を取得するため、クエリは、まずフィルタに一致する最初の行のインデックスをスキャンし、一致しない行に遭遇するまでスキャンを進めます。連続した行に結果セット全体が含まれるようにするため、他のプロパティよりも前に、不等式フィルタで使われているプロパティを基準として行を並べ替える必要があります。そのため、クエリで 1 つ以上の不等式フィルタとともに 1 つ以上の並べ替え順序を指定している場合は、最初の並べ替え順序で参照するプロパティが不等式フィルタで指定されているプロパティと同じものでなければなりません。次に有効なクエリを示します。

SELECT * FROM Person WHERE birth_year >= :min_birth_year
                     ORDER BY birth_year, last_name

次のクエリは、不等式フィルタで使われているプロパティを基準として並べ替えを行っていないため無効です。

SELECT * FROM Person WHERE birth_year >= :min_birth_year
                     ORDER BY last_name                   # ERROR

同様に、次のクエリは不等式フィルタで使われているプロパティが最初に並べ替えられていないため無効です。

SELECT * FROM Person WHERE birth_year >= :min_birth_year
                     ORDER BY last_name, birth_year       # ERROR

複数の値を持つプロパティは予期せぬ動作をする場合がある

同じプロパティに対して複数の値があるエンティティでは、クエリのフィルタや並べ替え順序に対する動作が予期しない意外なものになる場合があります。これはインデックス付けの仕組みによります。

特定のプロパティに対して複数の不等式フィルタが使われているクエリの場合、そのプロパティの個別の値の少なくとも 1 つがフィルタの「すべて」を満たす場合のみ、エンティティがクエリと一致するものとみなされます。たとえば、種類が Widget のエンティティのプロパティ x の値が 12 である場合、クエリと一致しません

SELECT * FROM Widget WHERE x > 1
                       AND x < 2

エンティティの x 値は、それぞれいずれかのフィルタを満たしていますが、どちらも単体では両方のフィルタを満たしていません。これは等式フィルタには適用されない点に注意してください。たとえば同じエンティティであっても、次のクエリは満たすことになります。

SELECT * FROM Widget WHERE x = 1
                       AND x = 2

エンティティの x 値は、個別では両方のフィルタ条件を満たすものがないことに注目してください。

不等(!=)演算子は、「値はそれ以外である」テストとして機能します。たとえば、次のクエリをご覧ください。

SELECT * FROM Widget WHERE x != 1

このクエリは、Widget の値が x 以外のすべての 1 エンティティに一致します。

同様に、複数の値を持つプロパティの並べ替え順序も通常とは異なります。このようなプロパティは一意の値ごとに 1 回しかインデックスに表れないため、インデックスに表れる最初の値によってエンティティの並べ替え順序が決定されます。

  • クエリ結果を昇順で並べ替えると、順序付けにはプロパティの最小値が使用されます。
  • クエリ結果を降順で並べ替えると、順序付けには最大値が使用されます。
  • その他の値は、並べ替え順序にも値の数にも影響しません。

これにより、通常とは異なる結果になります。つまり、昇順降順の両方で、プロパティ値が 19 であるエンティティが、プロパティ値が 4567 のエンティティより前に表示されます。

トランザクション内のクエリは祖先フィルタを含んでいなければならない

Cloud Datastore のトランザクションは、同じエンティティ グループ(共通の祖先を持つ子孫)に属するエンティティに対してのみ機能します。この制限を遵守するためには、トランザクション内で実行するすべてのクエリに、トランザクション内の他のオペレーションと同じエンティティ グループに属している祖先を指定する祖先フィルタを含める必要があります。

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

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

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