LoginSignup
84
33

More than 3 years have passed since last update.

Firestoreでwhereでしているフィールドとorderbyしたいフィールドが違うので複合インデックスを作る

Last updated at Posted at 2019-10-13

Firestoreはいろいろ制限がある。それでも便利なのでいろいろ試す。

私はポイントバリューを扱うアプリをよく書きます。バリュー操作自体はトランザクション処理もできるので、Firestoreでも安心して処理できます。で、処理時にtransactionsコレクションに下記のようなスキーマのdocumentを処理の度に残すとします。

処理した時間と、どのような処理をしたかを記録するとします。

{
    createdAt: 2019-10-13 09:14:11
    operation: "SEND" // or "Receive"
}

問題無いケース

全体のログを降順で見たい場合、

db.collection('transactions')
    .orderby('createdAt','desc').get();

というようになります。SQLで書くと、下記のような感じとなりますが、

select * from transactions order by createdAt desc;

この処理は特に問題ありません。

問題(というか操作が必要)となるケース

ただ、SEND処理だけを操作時間でソートしたい場合、(何もしないと)エラーになります。

db.collection('transactions')
    .where('operation','==','SEND')
    .orderby('createdAt','desc').get();

SQLで書くと、

select * from transactions where operation = 'SEND' order by craetedAt desc;

という何の変哲もないクエリです。

エラーの原因は、whereの条件で利用しているoperationとorderbyで別のフィールドを利用しているからです。
このクエリを実行すると、下記のようなエラーがでます。

{ Error: 9 FAILED_PRECONDITION: The query requires an index. You can create it here: https://console.firebase.google.com/v1/r/project/xxxxx/firestore/indexes?create_composite=ClNwcm9qZWN0cy9jd3NlcnZlci02Y2ZiMy9kYXRhYmFzZXMvKGRlZmF1bHQpL2NvbGxlY3Rpb25Hcm91cHMvdHJhbnNhY3Rpb25zL2luZGV4ZXMvXxABGg0KCW9wZXJhdGlvbhABGg0KCWNyZWF0ZWRBdBACGgwKCF9fbmFtZV9fEAI
    at callErrorFromStatus (/Users/xxxx/fire_test/node_modules/@grpc/grpc-js/build/src/call.js:30:26)
    at Http2CallStream.call.on (/Users/xxxx/fire_test/node_modules/@grpc/grpc-js/build/src/call.js:79:34)
    at Http2CallStream.emit (events.js:203:15)
    at process.nextTick (/Users/xxxx/fire_test/node_modules/@grpc/grpc-js/build/src/call-stream.js:75:22)
    at process._tickCallback (internal/process/next_tick.js:61:11)

よく読むと、「このクエリにはindexがいるぞ、以下のURLに行けば作れるよ」と親切に書いてくれています。
リンクのURLに行くと、そのまま「作るか?」と聞いてくるので「作る」とすればいいようです。

下記のように適切なindexを作ってくれるようです。

Kobito.cC66iJ.png

作成した上で、エラーとなったクエリを実行すると、問題なくクエリが実行されます。

84
33
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
84
33