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の気持ちが強すぎる。


Profile picture

ぴーやま
プログラミングを嗜んでします。中華料理で出てくるたまごふわふわのコーンスープが好きです。