Datastore では一部のメタデータにプログラムからアクセスできます。これによりメタプログラミングやバックエンドの管理機能の実装が可能となり、一貫性のあるキャッシュ保存が簡単になります。これは、アプリケーション用にカスタム Datastore ビューアを作成する場合などに役立ちます。使用できるメタデータとしては、アプリケーションが使用するエンティティ グループ、名前空間、エンティティの種類、プロパティに関する情報のほか、各プロパティのプロパティ表現などが挙げられます。
アプリケーションに関する一部のメタデータは、 Google Cloud コンソールの Datastore ダッシュボードでも提供されています。ただし、ここに表示されるデータは、いくつかの重要な側面において関数から返されるデータとは異なります。
- 鮮度: API を使用してメタデータを読み取ると最新のデータが取得されますが、ダッシュボードのデータが更新されるのは 1 日 1 回だけです。
- 内容: ダッシュボードの一部のメタデータは API 経由では使用できません。また、その逆の場合もあります。
- 速度:メタデータの取得とクエリは、Datastore の取得とクエリと同じ方法で課金されます。名前空間、種類、プロパティに関する情報をフェッチするメタデータ クエリは、実行速度が遅いのが一般的です。目安としては、N 個のエンティティを返すメタデータ クエリにかかる時間は、それぞれが単一のエンティティを返す N 個の通常のクエリにかかる時間とほぼ同じです。また、プロパティ表現クエリ(キーのみではないプロパティ クエリ)は、キーのみのプロパティ クエリよりも遅くなります。エンティティ グループのメタデータに対するメタデータ取得は、通常のエンティティを取得する場合よりもある程度は高速になります。
エンティティ グループのメタデータ
Cloud Datastore では、エンティティ グループの「バージョン」にアクセスできます。バージョンは正数であり、エンティティ グループに変更が加えられるたびに増加します。
エンティティ グループのバージョンを取得するには、真に正の __version__ プロパティを含む特別な疑似エンティティに対して get() を呼び出します。疑似エンティティのキーは、Entities.createEntityGroupKey() メソッドを使って作成できます。
従来の動作
エンティティ グループのバージョンの従来の動作では、エンティティ グループのバージョンはエンティティ グループに変更が加えられたときにのみ増加します。たとえば、エンティティ グループ メタデータの従来の動作を使用して、エンティティ グループに対する複雑な祖先クエリのキャッシュ整合性を確保できます。
この例では、クエリ結果(一致する結果の数)をキャッシュに保存し、エンティティ グループのバージョンの従来の動作を利用して、キャッシュに保存された値が最新であればそれを使用します。
書き込みが行われたことのないエンティティ グループの場合、__entity_group__ エンティティが存在しないことがあります。
メタデータ クエリ
Java クラス Entities は com.google.appengine.api.datastore パッケージで定義されており、メタデータ クエリ用に予約された特別なエンティティの種類が 3 つ用意されています。これらの種類は、Entities クラスの静的定数で示されます。
| 静的定数 | エンティティの種類 |
|---|---|
Entities.NAMESPACE_METADATA_KIND |
__namespace__ |
Entities.KIND_METADATA_KIND |
__kind__ |
Entities.PROPERTY_METADATA_KIND |
__property__ |
これらの種類は、アプリケーションにすでに存在する可能性がある同じ名前の他のエンティティとは競合しません。このような特殊な種類に対してクエリを実行することで、目的のメタデータを含むエンティティを取得できます。
メタデータ クエリによって返されるエンティティは、Datastore の現在の状態に基づいて動的に生成されます。種類が __namespace__、__kind__、__property__ のローカル Entity オブジェクトを作成することはできますが、Datastore に保存しようとすると IllegalArgumentException となり、失敗します。
メタデータ クエリを実行する最も簡単な方法は、低水準 Datastore API を使用することです。たとえば、次のコードは、アプリケーションのすべての名前空間の名前を出力します。
名前空間クエリ
アプリケーションで Namespaces API を使う場合、名前空間クエリを使用すると、アプリケーションのエンティティで使用されているすべての名前空間を検索できます。これにより、複数の名前空間にまたがる管理機能などのアクティビティを実行できます。
名前クエリは、キー名が名前空間の名前である特別な種類 __namespace__ のエンティティを返します。(空の文字列 "" で示されるデフォルトの名前空間は例外です。空の文字列は有効なキー名ではないため、この名前空間には数値 ID 1 が代わりにキーとして設定されます)。このタイプのクエリは、特殊な疑似プロパティ __key__ を対象とした範囲のフィルタリングだけをサポートします。このプロパティの値はエンティティのキーです。結果は __key__ 値の昇順で並べ替えることができます(降順にすることはできません)。__namespace__ エンティティはプロパティを持たないため、キーのみのクエリでもキーのみではないクエリでも同じ情報が返されます。
次の例は、アプリケーションの名前空間のうち、指定された 2 つの名前、start と end の間にある名前空間のリストを返します。
種類クエリ
種類クエリは、キー名がエンティティの種類の名前である __kind__ という種類のエンティティを返します。このタイプのクエリは暗黙的に現在の名前空間に限定され、__key__ 疑似プロパティを対象とした範囲のフィルタリングだけをサポートします。結果は __key__ 値の昇順で並べ替えることができます(降順にすることはできません)。__kind__ エンティティはプロパティを持たないため、キーのみのクエリでもキーのみではないクエリでも同じ情報が返されます。
次の例は、名前が小文字で始まるすべての種類を出力します。
プロパティ クエリ
プロパティ クエリは、種類が __property__ であるエンティティを返します。これは、エンティティの種類に関連付けられたプロパティを示しますプロパティが P、種類が K で表現されるエンティティは次のように構築されます。
- エンティティのキーの種類は
__property__で、キー名は P です。 - 親エンティティのキーの種類は
__kind__で、キー名は K です。
プロパティ クエリの動作は、それがキーのみのクエリかキーのみではない(プロパティ表現)クエリかによって異なります。詳細については以降の説明をご覧ください。
プロパティ クエリ: キーのみ
キーのみのプロパティ クエリは、指定したエンティティの種類のインデックス付けされた各プロパティのキーを返します(インデックス付けされていないプロパティは含まれません)。次の例は、アプリケーションのエンティティの種類すべての名前と、それぞれに関連付けられているプロパティを出力します。
このタイプのクエリは暗黙的に現在の名前空間に限定され、疑似プロパティ __key__ を対象とした範囲のフィルタリングだけをサポートします。この場合、キーは __kind__ または __property__ エンティティを示します。結果は __key__ 値の昇順で並べ替えることができます(降順にすることはできません)。フィルタリングは種類とプロパティの(この順に並んだ)ペアに適用されます。たとえば、次のようなプロパティを持つエンティティがあるとします。
- プロパティを含む種類
Accountbalancecompany
- プロパティを含む種類
Employeenamessn
- プロパティを含む種類
Invoicedateamount
- プロパティを含む種類
Managernametitle
- プロパティを含む種類
Productdescriptionprice
このプロパティ データを返すクエリは次のようになります。
上のクエリは、次のデータを返します。
Employee: ssn
Invoice: date
Invoice: amount
Manager: name
結果には種類 Employee の name プロパティ、種類 Manager の title プロパティは含まれません。また、種類 Account と種類 Product のプロパティはすべて含まれません。これらのプロパティは、クエリに指定された範囲に含まれないためです。
プロパティ クエリは __kind__ キーまたは __property__ キーによる祖先フィルタリングもサポートしています。これにより、クエリの結果が単一の種類またはプロパティに限定されます。これを利用して、次の例に示すように特定のエンティティの種類に関連付けられたプロパティを取得できます。
プロパティ クエリ: キーのみではない(プロパティ表現)
キーのみではないプロパティ クエリは「プロパティ表現クエリ」と呼ばれ、種類とプロパティの各ペアで使用される表現に関する追加情報を返します(インデックス付けされていないプロパティは含まれません)。種類が K のプロパティ P に対して返されるエンティティには、対応するキーのみのクエリで返されるものと同じキーに加えて、プロパティの表現を返す追加の property_representation プロパティが存在します。このプロパティの値はクラス java.util.Collection<String> のインスタンスです。このインスタンスには、種類が K のエンティティで検出されたプロパティ P の表現ごとに 1 つの文字列が含まれます。
表現はプロパティ クラスとは異なり、複数のプロパティ クラスが同じ表現にマップされる場合があります(たとえば、java.lang.String と com.google.appengine.api.datastore.PhoneNumber の両方で STRING 表現が使用されています)。
次の表に、プロパティ クラスからその表現へのマッピングを示します。
| プロパティ クラス | 表現 |
|---|---|
java.lang.Byte |
INT64 |
java.lang.Short |
INT64 |
java.lang.Integer |
INT64 |
java.lang.Long |
INT64 |
java.lang.Float |
DOUBLE |
java.lang.Double |
DOUBLE |
java.lang.Boolean |
BOOLEAN |
java.lang.String |
STRING |
com.google.appengine.api.datastore.ShortBlob |
STRING |
java.util.Date |
INT64 |
com.google.appengine.api.datastore.GeoPt |
POINT |
com.google.appengine.api.datastore.PostalAddress |
STRING |
com.google.appengine.api.datastore.PhoneNumber |
STRING |
com.google.appengine.api.datastore.Email |
STRING |
com.google.appengine.api.users.User |
USER |
com.google.appengine.api.datastore.IMHandle |
STRING |
com.google.appengine.api.datastore.Link |
STRING |
com.google.appengine.api.datastore.Category |
STRING |
com.google.appengine.api.datastore.Rating |
INT64 |
com.google.appengine.api.datastore.Key |
REFERENCE |
com.google.appengine.api.blobstore.BlobKey |
STRING |
java.util.Collection<T> |
T の表現 |
次の例は、あるエンティティの種類の指定したプロパティのすべての表現を検出します。