Firebase Firestoreの「参照」データ型は何に適していますか?


189

新しいFirebase Firestoreを探索しているだけで、というデータ型が含まれていますreference。これが何をするのか私には分かりません。

  • 外部キーのようなものですか?
  • 他の場所にあるコレクションを指すために使用できますか?
  • reference実際の参照の場合、クエリに使用できますか?たとえば、userIdをテキストフィールドに格納する代わりに、ユーザーを直接指す参照を設定できますか?また、このユーザー参照をクエリに使用できますか?

18
Firebaseチームからのこのビデオはあなたのためにそれを分解すると思います:youtube.com/watch?v=Elg2zDVIcLo(4:36から視聴)
Adarsh '24年

回答:


91

参照は外部キーと非常によく似ています。

現在リリースされているSDKは、他のプロジェクトへの参照を保存できません。プロジェクト内では、参照は他のコレクション内の他のドキュメントを指すことができます。

他の値と同様にクエリで参照を使用できます:フィルタリング、順序付け、およびページング(startAt / startAfter)。

SQLデータベースの外部キーとは異なり、参照は単一のクエリで結合を実行するのに役立ちません。これらは依存ルックアップ(結合のように見える)に使用できますが、各ホップはサーバーへの別のラウンドトリップになるので注意してください。


9
可能なユースケースを共有できますか?その参照のフィールドをクエリすることは可能ですか?たとえば、friendsすべての友達をリストしたコレクションがあります(friends/myId)。次に、このドキュメントfriendsを別のドキュメントのフィールドで参照します(group/groupId)。そのグループにいる友達だけを表示して、次のようにしますwhere('friends.myId', '==', true)
ウィル

108
ところで、参照型を追加する例を含むようにドキュメントを更新すると便利な場合があります。
ウィル

11
これに関する情報が見つかりませんか?これにより、データベース構造全体が変更されます。詳細を知る必要があります...
Ruben

3
参照を使用してクエリする方法の例(できれば迅速)はありますか?現在、生のuidを文字列として格納することでそれを行うことができますが、それは正しくないようです。
ミッキーチョン

6
クエリは常に参照タイプで失敗するため、すべての参照タイプを文字列に変更する必要があります。参照タイプでクエリする方法について文字通り何も見つけることができません:(参照タイプでクエリする方法を誰かが見つけたら教えてください...
Sam Trent

133

Firestoreで参照を使用して私のために働いたことを以下に追加します。

他の答えが言うように、それは外部キーのようなものです。ただし、参照属性は参照ドキュメントのデータを返しません。たとえば、製品の属性の1つとしてuserRef参照を持つ製品のリストがあります。製品のリストを取得すると、その製品を作成したユーザーのリファレンスが得られます。しかし、それは私にその参照のユーザーの詳細を与えません。私は他のバックエンドをポインタを持つサービスとして使用しており、その前に "populate:true"フラグが付いているため、ユーザーの参照IDだけでなく、ユーザーの詳細を返すことができます。 )。

以下は、参照を設定し、製品リストのコレクションを取得して、指定されたユーザー参照IDからユーザーの詳細を取得するために使用したコードの例です。

コレクションに参照を設定します。

let data = {
  name: 'productName',
  size: 'medium',
  userRef: db.doc('users/' + firebase.auth().currentUser.uid)
};
db.collection('products').add(data);

コレクション(製品)と各ドキュメントのすべてのリファレンス(ユーザーの詳細)を取得します。

db.collection('products').get()
    .then(res => {
      vm.mainListItems = [];
      res.forEach(doc => {
        let newItem = doc.data();
        newItem.id = doc.id;
        if (newItem.userRef) {
          newItem.userRef.get()
          .then(res => { 
            newItem.userData = res.data() 
            vm.mainListItems.push(newItem);
          })
          .catch(err => console.error(err));
        } else {
          vm.mainListItems.push(newItem);  
        }

      });
    })
    .catch(err => { console.error(err) });

お役に立てれば


3
共有してくれてありがとう!Getパートの最初の行にタイプミスがあると思いますdb.collection('products').get()。ユーザーを直接取得してみましたか?newItem.userRef.get()代わりに機能するはずだと思いますdb.collection("users").doc(newItem.userRef.id).get()
セルゲイネフェディエフ2017

53
まず第一に、例をありがとう。彼らが将来のために「populate:true」を追加することを望みます。そうでない場合、参照を保存しても意味がありません。uidそれを介してと参照を保存するだけで同じことができます。
ユルゲン・Brandstetter

4
例をありがとう!しかし、ドキュメントをクエリするときに「populate」の種類のオプションがない場合、参照タイプを保存する意味は何ですか?誰もが知っている作成オプションがある場合は、私に知らせてください。
Harshil Shah

18
つまり、実際には外部キーのようなものではありません。私にはそれは基本的に何もしません- reference真の外部キーとして使用できない場合に機能する必要があるのはなぜですか?
ジャンD'アルメ

14
したがって、referenceoverの唯一の利点は、参照を直接string呼び出すことができることですget()。まだあまり役に立ちません。参照に対応するオブジェクトを自動的に入力するオプションを追加してほしいと思います!
モルグラー

16

参照によるクエリのJavaScriptソリューションをお探しの方-コンセプトは、クエリステートメントで「ドキュメント参照」オブジェクトを使用する必要があることです

teamDbRef = db.collection('teams').doc('CnbasS9cZQ2SfvGY2r3b'); /* CnbasS9cZQ2SfvGY2r3b being the collection ID */
//
//
db.collection("squad").where('team', '==', teamDbRef).get().then((querySnapshot) => {
  //
}).catch(function(error) {
  //
});

(ここでの答えに対する称賛:https : //stackoverflow.com/a/53141199/1487867

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.