web-dev-qa-db-ja.com

Firestore-ドキュメントから特定のフィールドを取得します

必要なもの:

Firestoreの記事またはメモをそれぞれのフィールドで保存したい:

しかし、記事のリストを表示するとき、「コンテンツ」フィールドは必要ありません(帯域幅を節約するため)。私はそれを読んだことがありますが(間違っているかもしれません)、Firestoreを使用してドキュメントから特定のフィールドのみを取得するクエリを作成することはできません。

記事から特定の列を取得するのが通常のSQLである場合(コンテンツなし)、次のようになります。

SELECT title, creation_date, ...
FROM table_name;

そのため、2つのルートレベルコレクションのコンテンツを分離することを選択しました(柔軟性とスケーラビリティのため)


私の現在の構造:

記事コレクション:

  - `articles` [collection]
    - `ARTICLE_ID` [document]
      - `creatorId` [field]
      - `title` [field]
      - `date` [field]
      - `owners` [obj field]
          - {user1_id}: true
          - {user2_id}: true
          ...

コンテンツコレクション:

  - `contents` [collection]
    - `{ARTICLE_ID}` [document]
      - `content` [field]

リアルタイムで記事リストを取得するには:

firebase.firestore().collection('articles')
  .where(`owners.${user.uid}`, '==', true)
  .onSnapshot(querySnapshot => {
    const articles = []
    querySnapshot.forEach((doc) => {
      articles.Push({
        id: doc.id,
        ...doc.data()
      })
    })
    // do something with articles array
  })

別のビューで表示して、記事全体とそのコンテンツを取得するには:

const db = firebase.firestore()
const articleRef = db.collection('articles').doc(articleId)
const contentRef = db.collection('contents').doc(articleId) // same Id as article

articleRef.get().then(articleDoc => {
  if (articleDoc.exists) {
    contentRef.get().then(contentDoc => {
      if (contentDoc.exists) {
        const article = {
          ...articleDoc.data(),
          ...contentDoc.data()
        }
        // full article obj
      }
    })
  } 
})

私の質問

  • 2つのクエリ(getArticleとgetContent)を同時に実行して、クエリをネストする代わりにPromise.all()で待機する方が良いと思いますか?

  • 1つのクエリで記事やそのコンテンツを取得するより効率的な方法はありますか?いくつかのヒントやアイデアはありますか?

事前にどうもありがとうございました!

14
BlackCode

どちらのアプローチも、他のアプローチより適切ではありません。しかし、いくつかの重要な違いがあります。

  1. 読み取りをネストすると、2番目の読み取りは最初の読み取りが完了した後にのみ開始されます。 Promise.all()を使用すると、両方の読み取りが同時に開始されるため、(部分的に)並行して実行できます。

  2. 一方、Promise.all()を使用すると、完了ハンドラー(then()で実行するコード)は、両方のドキュメントがロードされるまで実行されません。呼び出しをネストすると、最初のドキュメントが読み込まれた後にUIを更新できます。

最終的に、違いは小さい可能性があります。しかし、それらはあなたのユースケースにとって重要かもしれないので、結果を測定し、あなたに最適なものを見てください。

6

Firestore Query.select ドキュメントによると、必要なフィールドを選択できるはずです。

let collectionRef = firestore.collection('col');
let documentRef = collectionRef.doc('doc');

return documentRef.set({x:10, y:5}).then(() => {
  return collectionRef.where('x', '>', 5).select('y').get();
}).then((res) => {
  console.log(`y is ${res.docs[0].get('y')}.`);
});
1
abraham

Firebase Hostingは、記事などの静的コンテンツに最適です。たとえば、 AMP-HTML を見ると、ページの読み込みが非常に高速であり、Edgeキャッシングの利点が強調されています。 Firebaseホスティングは グローバルエッジキャッシュもサポートするように広告されています です。

FirestoreおよびFirebase Realtime Databaseはデータベースエンジンです。これらは記事を提供するための適切なツールではありません。

0
Ron Royston