経緯
RaspberryPiのPHPから、Google Cloud Datastoreに繋いでクエリを発行するも、「no matching index found.」と返されて怒られる。
実行するクエリによって、複合インデックスを登録する必要があるが、調べてもGAE環境でしか見当たらず、困ったのでそのメモ。
環境
RaspberryPi3B
php7
gloudコマンドラインツール
サービスアカウントあり
Datastoreのエンティティ
- door インデックス登録済み
- room インデックス登録済み
- timestamp インデックス登録済み
発行クエリ
$query = $datastore->gqlQuery('SELECT * FROM Rooms WHERE room = @room ORDER BY timestamp DESC LIMIT @limit', [
'bindings' => [
'room' => $room,
'limit' => 1
]
]);
実行結果
PHP Fatal error: Uncaught Google\Cloud\Core\Exception\BadRequestException: {
"error": {
"code": 400,
"message": "no matching index found. recommended index is:\n- kind: Rooms\n properties:\n - name: room\n - name: timestamp\n direction: desc\n",
"status": "FAILED_PRECONDITION"
}
}
対策
エラーに書いてある通り、マッチするインデックスが無いと言われるので、インデックスの設定を行う。
インデックス設定
recommended index is と書いてくれてるので、そのまま index.yaml に書く。
index.yaml
indexes:
- kind: Rooms
properties:
- name: room
- name: timestamp
direction: desc
この内容を反映させる方法がこちら
gcloud ツールを使用したアプリケーション テストとインデックス管理
$ gcloud datastore create-indexes ./index.yaml
Configurations to update:
descriptor: [./index.yaml]
type: [datastore indexes]
target project: [xxxxxxxxxxxxxx]
Do you want to continue (Y/n)? y
これでOK。作成されるまでに時間がかかる。急いでクエリを実行すると、以下のように怒られる。
PHP Fatal error: Uncaught Google\Cloud\Core\Exception\BadRequestException: {
"error": {
"code": 400,
"message": "The index for this query is not ready to serve. See the Datastore Indexes page in the Admin Console.",
"status": "FAILED_PRECONDITION"
}
}
焦っちゃダメよ、管理画面を見てね。
結果
array(1) {
[0]=>
array(2) {
["room"]=>
string(5) "room7"
["door"]=>
string(5) "close"
}
}
で、めでたく取得できました。おーいえ。