firestoreを使ってみて
思ったことをメモ
クエリの制限多い
・複数のフィールドに範囲フィルタを適用するクエリ(前のセクションの説明を参照)。
・複数のコレクションまたはサブコレクションにわたる単一のクエリ。各クエリは、ドキュメントの単一コレクションに対して実行されます。データ構造がクエリにどのように影響するかについては、データ構造の選択をご覧ください。
・個々の配列メンバーのクエリ。ただし、配列、リスト、セットの操作のテクニックを使用して、配列のようなデータをモデル化およびクエリすることは可能です。
・論理 OR クエリ。この場合は、OR 条件ごとに独立したクエリを作成し、アプリでクエリ結果を結合する必要があります。
・!= 句が含まれるクエリ。この場合は、「より大きい」クエリと「より小さい」クエリに、クエリを分割する必要があります。たとえば、クエリ句 where("age", "!=", "30") はサポートされませんが、2 つのクエリ(句 where("age", "<", "30") が含まれるクエリと句 where("age", ">", 30) が含まれるクエリ)を結合することで、同じ結果セットを取得できます。
引用元:https://firebase.google.com/docs/firestore/query-data/queries
範囲選択とorderは同じフィールドじゃないとだめ
usersコレクションからuser_typeがownerのユーザーを作成日で指定してソートして取得みたいな時
let usersRef = await db
.collection('users')
.where('user_type', '==', owner)
if (req.query.max_created_at) {
const max_created_at = req.query.max_created_at
usersRef = await booksRef.where(created_at, '<', new Date(created_at))
}
if (req.query.min_created_at) {
const min_created_at = req.query.min_created_at
usersRef = await usersRef.where(created_at, '>', new Date(min_updated_at))
}
if(!req.query.max_created_at && !req.query.min_created_at) {
usersRef = await usersRef.where(created_at, '<', new Date())
}
// これはできるけど
usersRef = await usersRef.orderBy(created_at, DESC).limit(limit)
// これはだめ
usersRef = await usersRef.orderBy(updated_at, DESC).limit(limit)
「範囲比較(<、<=、>、>=)は、1 つのフィールドでのみ実行できます。」
https://firebase.google.com/docs/firestore/query-data/queries
orderBy
は複数指定できるけど
「範囲比較(<、<=、>、>=)のフィルタがある場合、最初の並べ替えは同じフィールドで行う必要があります。」
https://firebase.google.com/docs/firestore/query-data/order-limit-data?hl=ja
あと、このあとにさらにstarが100以下のユーザーに絞り込みたいよと思っても
usersRef = await usersRef.where('star', '<', 100)
とかはできない。
「!=」できない
exclude_user_idを除外したownerのuserリストがほしい場合
query1と
const exclude_user_id = hoge
let userRef = await db
.collection('users')
.where('user_type', '==', owner)
.where(admin.firestore.FieldPath.documentId(), '<', exclude_user_id)
query2を作って
let usersRef2 = await db
.collection('users')
.where('user_type', '==', owner)
.where(admin.firestore.FieldPath.documentId(), '>', exclude_user_id)
結果をガチャンてしないといけない。
めんどくさい。
https://stackoverflow.com/questions/49602362/query-firestore-by-inequality
ORもnotも、とにかくアプリ側でクエリ結果を結合する必要がある。
というかこれはむしろデータベースの設計を見直せという話。今の私はRDBの気持ちが強すぎる。