
待ちに待ったFirestoreにARRAY_CONTAINS_ANYとIN検索がキタ!!
v2.5.0よりの新機能
Features
・ introduces ARRAY_CONTAINS_ANY and IN to operator enum (2c8869d)
Release v2.5.0 · googleapis/nodejs-firestore
Features introduces ARRAY_CONTAINS_ANY and IN to operator enum (2c8869d) Bug Fixes deps: bump google-gax to 1.7.5 (#786) (e5763ba)
何が革命的か??
例えば、自分が今持っている材料を条件に、料理一覧から対象の料理を持ってくるシステムがあるとする。
例:人参と玉葱が余っているから、どちらかか、またはその両方が 使える料理を探したい。
構成:

今まで
「パターン1」: クエリを複数回投げ、プログラムで重複を後で削除する

db.collection("FoodList").where("材料", "array-contains", "玉ねぎ").get()
db.collection("FoodList").where("材料", "array-contains", "人参").get()検索したい材料の分クエリを投げ、その結果をプログラムで結合する。

問題:人参と玉ねぎを両方使う料理は重複して取れてしまう。
検索する材料の種類が増えれば増えるほど、重複が増える。
「パターン2」: すべて取得し、プログラムで対象外のデータを削除する

db.collection("FoodList").get()
最初に対象のCollectionのデータを取得し、後でプログラム側で指定の材料が入っていないデータを削除する。

問題:毎回すべてのデータを取得するので、データの量が増えれば増えるほど、転送量が増えるため遅くなる。
また、パターン2とパターン3の問題として、ページネーションを実装しにくい点にある。
例えば,1ページ10件のみデータを出すページネーションを実装した際に、事前に10件だけとってくるということができない。
※queryを発行して、プログラムで削ってみるまで全文で対象のデータが何件あるかを把握できないため
よって双方とも、最初の検索でネットワーク転送量が余分にかかってしまう。
「パターン3」Algoliaなどのサードパーティーサービスを使う
これまでであれば、このパターンが一番多かったであろう。
これからの話しをしよう
array-contains-any を使い1発で取得する
db.collection("FoodList").where("材料", "array-contains-any", ["人参", "玉ねぎ"]).get()
こうすることにより、材料配列に人参か玉ねぎがあるドキュメントを一発で取得することができる。
※ただし、2019/11/08時点では 最大10種類の値でしか検索できないので注意。
この機能をまっていたんだ!
IN検索については別途追記していきます。
参考
Cloud Firestore Now Supports IN Queries!
Hello, Cloud Firestore developers! We wanted to let you know about some useful new querying features we’ve added to Cloud Firestore this week. Starting with… in queries! With the in query, you can query a specific field for multiple values (up to 10) in a single query. You do this by passing a list…

Kohei Kondo