Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9086

Firestoreの複合インデックスでつまったところまとめ

$
0
0

対象読者

複合インデックスを登録しているのに取得できない方

解決方法

まず、エラー内容を確認します。firebase Functionsを使っている方はfirebaseのコンソールに入って、Functionsのログからエラーを確認してください。もし使われていない方は、例外処理によってエラー内容を返して確認してみてください。以下のエラー(一部抜粋)が出力されていると思います。

"details": "The query requires an index. You can create it here: https://console.firebase.google.com/v1/r/project/[projectID]/firestore/indexes?create_composite=[文字列]",

「クエリを実行するにはインデックスが必要なので作ってくださいね」と書かれており、親切にURLも記載してくれています:clap:。アクセスすると、Google Cloud PlatFormがブラウザで開き、インデックスを登録するかを聞かれますので、そのままインデックスを登録をしてください。
登録が成功された状態でAPIを実行すると、無事にデータが取得できるようになります。(この解決方法は公式ドキュメントにも記載されています。)

実際につまったところと原因

以下のような構造をとったデータが保存されているとします。

interface
interfaceLog{user_id:stringmessage_id:stringcreated_at:string}

そのデータを以下の条件で取得したいと仮定します。
①あるユーザーのログをメッセージごとに並び替え、さらに作成日の順に並び替えて取得する
②あるメッセージのログをユーザーごとに並び替え、さらに作成日の順に並び替えて取得する

model/index.js
// ①の場合のクエリsnapshot=awaitdocRef.where('user_id','==',userId).orderBy('message_id').orderBy('created_at').get()// ②の場合のクエリsnapshot=awaitdocRef.where('message_id','==',messageId).orderBy('user_id').orderBy('created_at').get()

このクエリに対し、以下のインデックスを事前に登録していました。

コレクションIDインデックス登録されるフィールドクエリのスコープ
collection_iduser_id 昇順 message_id 昇順 created_at 昇順コレクション

※表の列の名前は、それぞれfirebaseのコンソールでFirestoreにアクセスし、インデックスに書かれているものです。Google Cloud PlatFormで見た場合は
  インデックス登録されるフィールド → フィールド
  クエリのスコープ → Query scope
となっています。

この状態で実際にAPIを実行すると、①は取得できて②ではエラーになります。
そして、上記の解決方法に記載の通りクエリを作成すると、インデックスが以下のようになります。

コレクションIDインデックス登録されるフィールドクエリのスコープ
collection_iduser_id 昇順 message_id 昇順 created_at 昇順コレクション
collection_idmessage_id 昇順 user_id 昇順 created_at 昇順コレクション

ここで、もう一度APIを実行すると先ほどエラーだった②も取得できるようになります。
つまり、原因はクエリで指定している複数のインデックスをその順にインデックスに登録していなかったこととなります。今回のケースでは、使用したフィールドは同じでしたが、厳密には条件が異なっており、インデックスも別々に定義する必要があったようです。

このように条件が違えばインデックスを新たに定義すればいいと言うことが分かったのですが、やみくもにインデックスを作成していると利用料金(インデックスはストレージの料金として計上されるみたいです)が無駄にかかってしまうので、インデックス マージを活用して重複するインデックスを削減する、と言ったことも可能みたいです。


公式ドキュメントを読んでみて「複合インデックスを登録すると複数のフィールドを組み合わせたインデックスを作成でき、それによってデータが取得できるようになる」と自分なりに解釈をしてみたのですが、組み合わせであっても順番を担保しないといけないのは何故なのでしょうか、、詳しい方いらっしゃいましたら教えていただきたいです、、:pray:


Viewing all articles
Browse latest Browse all 9086

Latest Images

Trending Articles