web-dev-qa-db-ja.com

Google Firestore-1回の往復で複数のIDでドキュメントを取得する方法

Firestoreへの1回の往復(ネットワーク呼び出し)でIDのリストから複数のドキュメントを取得できるかどうか疑問に思っています。

55
Joon

node内にいる場合:

https://github.com/googleapis/nodejs-firestore/blob/master/dev/src/index.ts#L701

/**
* Retrieves multiple documents from Firestore.
*
* @param {...DocumentReference} documents - The document references
* to receive.
* @returns {Promise<Array.<DocumentSnapshot>>} A Promise that
* contains an array with the resulting document snapshots.
*
* @example
* let documentRef1 = firestore.doc('col/doc1');
* let documentRef2 = firestore.doc('col/doc2');
*
* firestore.getAll(documentRef1, documentRef2).then(docs => {
*   console.log(`First document: ${JSON.stringify(docs[0])}`);
*   console.log(`Second document: ${JSON.stringify(docs[1])}`);
* });
*/
43

いいえ、現在、Cloud Firestore SDKを使用して複数の読み取り要求をバッチ処理する方法はないため、すべてのデータを一度に読み取ることができることを保証する方法はありません。

しかし、フランク・ファン・パフェレンが上記のコメントで述べたように、これは、3つのドキュメントの取得が1つのドキュメントの取得の3倍遅いことを意味しません。ここで結論を出す前に、独自の測定を実行することをお勧めします。

9
Sam Stern

次のような関数を使用できます。

function getById (path, ids) {
  return firestore.getAll(
    [].concat(ids).map(id => firestore.doc(`${path}/${id}`))
  )
}

単一のIDで呼び出すことができます:

getById('collection', 'some_id')

またはIDの配列:

getById('collection', ['some_id', 'some_other_id'])
7
JP de la Torre

確かにこれを行う最良の方法は、Firestoreの実際のクエリをクラウド機能に実装することですか?クライアントからFirebaseへのラウンドトリップコールは1回だけになります。

とにかく、このサーバー側のようなすべてのデータアクセスロジックを保持する必要があります。

内部的にはFirebase自体への呼び出しの数は同じになる可能性がありますが、それらはすべて外部ネットワークではなく、Googleの超高速相互接続を介して行われ、フランクファンパフェレンが説明したパイプラインと組み合わせると、優れたパフォーマンスが得られますこのアプローチ。

5
Chris Wilson

実際には、このようにfirestore.getAllを使用します

async getUsers({userIds}) {
    const refs = userIds.map(id => this.firestore.doc(`users/${id}`))
    const users = await this.firestore.getAll(...refs)
    console.log(users.map(doc => doc.data()))
}

またはpromise構文を使用

getUsers({userIds}) {
    const refs = userIds.map(id => this.firestore.doc(`users/${id}`))
    this.firestore.getAll(...refs).then(users => console.log(users.map(doc => doc.data())))
}
3
Sebastian

KotlinでAndroid SDKを使用してこのようにする方法を次に示します。
必ずしも1回の往復である必要はありませんが、結果を効果的にグループ化し、ネストされた多くのコールバックを避けます。

val userIds = listOf("123", "456")
val userTasks = userIds.map { firestore.document("users/${it!!}").get() }

Tasks.whenAllSuccess<DocumentSnapshot>(userTasks).addOnSuccessListener { documentList ->
    //Do what you need to with the document list
}

特定のドキュメントを取得する方が、すべてのドキュメントを取得して結果をフィルタリングするよりもはるかに優れていることに注意してください。これは、Firestoreがクエリ結果セットに対して課金するためです。

0
Markymark

これは現時点ではFirestoreでは不可能なようです。アレクサンダーの答えが受け入れられる理由がわかりません。彼が提案する解決策は、「ユーザー」コレクション内のすべてのドキュメントを返すだけです。

何をする必要があるかに応じて、表示する必要がある関連データの複製を検討し、必要な場合にのみ完全なドキュメントを要求する必要があります。

0
Horea