2017-12-22 17 views
1

私は次の構造を持つクラウドFirestore DBを持っている:Cloud Firestoreクエリで複数のドキュメントを結合するにはどうすればよいですか?

  • ユーザー
    • [UID]
      • 名: "テストユーザー"
  • 投稿
    • [id]
      • 内容:「ちょっとテストポスト」。
      • タイムスタンプ:(2017年12月22日)
      • UID:[UID]

実際のDBに存在するより多くのデータがあるが、上記は単なるコレクション/文書を示します/フィールド構造。

私は、私が投稿を表示している投稿者の名前を表示したいWebアプリケーションのビューを持っています。私は記事をフェッチするには、以下のクエリを使用しています:

let loadedPosts = {}; 
posts = db.collection('posts') 
      .orderBy('timestamp', 'desc') 
      .limit(3); 
posts.get() 
.then((docSnaps) => { 
    const postDocs = docSnaps.docs; 
    for (let i in postDocs) { 
    loadedPosts[postDocs[i].id] = postDocs[i].data(); 
    } 
}); 

// Render loadedPosts later 

私は何をしたいが、ポストのuidフィールドに格納されているUIDでユーザーオブジェクトを照会し、対応するloadedPostsオブジェクトにユーザーの名前のフィールドを追加しています。一度に1つのポストしか読み込んでいなかった場合は、問題はありません。オブジェクトが返ってくるのを待ってから、.then()関数で別のクエリをユーザ文書に作成します。

しかし、私は一度に複数の投稿文書を取得しているため、正しい投稿を.get()の各投稿のuser/[uid]文書で呼び出すと、正しいユーザーを正しい投稿にマップする方法がわかりません。

誰もがこの問題に対して洗練されたソリューションを考えることはできますか?

答えて

4

私は1人のユーザーのdoc callを行い、必要な投稿を呼び出します。

let users = {} ; 
let loadedPosts = {}; 
db.collection('users').get().then((results) => { 
    results.forEach((doc) => { 
    users[doc.id] = doc.data(); 
    }); 
    posts = db.collection('posts').orderBy('timestamp', 'desc').limit(3); 
    posts.get().then((docSnaps) => { 
    docSnaps.forEach((doc) => { 
    loadedPosts[doc.id] = doc.data(); 
    loadedPosts[doc.id].userName = users[doc.data().uid].name; 
    }); 
}); 
+0

4の代わりに2つのコール、nice! – saricden

+3

これは、最後の3つの投稿を作成したユーザーだけでなく、すべての*ユーザーを読み込みます。これは開発中にうまくいくかもしれませんが、ユーザーを増やすと不必要なデータがますます読み込まれるようになります。 –

3

それは私にはかなり単純なようだ:

let loadedPosts = {}; 
posts = db.collection('posts') 
      .orderBy('timestamp', 'desc') 
      .limit(3); 
posts.get() 
.then((docSnaps) => { 
    docSnaps.forEach((doc) => { 
    loadedPosts[doc.id] = doc.data(); 
    db.collection('users').child(doc.data().uid).get().then((userDoc) => { 
     loadedPosts[doc.id].userName = userDoc.data().name; 
    }); 
    }) 
}); 

ユーザーを複数回ロードしないようにしたい場合は、ユーザデータ、クライアント側にキャッシュすることができます。その場合は、ユーザー読み込みコードをヘルパー関数に組み込むことをお勧めします。しかし、それは上記のバリエーションになります。

+0

私はちょうどテストし、それは完全に動作します!私はこのように近づけば、doc.idはユーザget()、then()の呼び出しのたびに、最後の反復の文書のIDになり、私の部分のループでコールバックを定義することを誤解してしまいます。 – saricden

-1

ただ1つのuserdocクエリと必要なpostsdoc呼び出しを行います。

+0

申し訳ありませんが、parmigianaの元の回答から.limit(3)を差し引いたものと同じです。他の人の回答をコピーしないでください。 – saricden

関連する問題