web-dev-qa-db-ja.com

消防署のデータ構造のベストプラクティスは何ですか?

Firebaseを使用してブログアプリを作成しています。

データ構造のベストプラクティスを知りたいです。

私の知る限り、2つのケースがあります。 (私はreactnativeを使用しています)

ケース1:

_posts
  -postID
   -title,content,author(userID),createdDate,favoriteCount

favorites
  -userID
    -favoriteList
      -postID(onlyID)
      -postID(onlyID)
_

この場合、たとえば、お気に入りの投稿を取得する必要がある場合です。

_firebase.firestore().collection(`favorites/${userID}/favoriteList`)
    .get()
    .then((snapshot) => {
      snapshot.forEach((favorite) => {
        firebase.firestore().collection(`favorites/`).doc(`${favorite.id}`)
          .get()
          .then((post) => {
          myPostList.Push(post.data())
        });
  });
_

この場合、お気に入りの投稿をcreatedDateで並べ替えることはできません。したがって、クライアント側を並べ替える必要があります。その場合でも、limit()関数は使用しません。

ケース2:

_posts
  -postID
  -title,content,author(userID),createdDate,favoriteCount

favorites
  -userID
     -favoriteList
       -postID
         -title,content,author(userID),createdDate,favoriteCount
       -postID
         -title,content,author(userID),createdDate,favoriteCount
_
_firebase.firestore().collection(`favorites/${userID}/favoriteList`).orderBy('createdDate','desc').limit(30)
    .get()
    .then((snapshot) => {
      snapshot.forEach((post) => {
        myPostList.Push(post.data())
      });
  });
_

この場合、作成者がお気に入りの投稿を変更すると、すべてのお気に入りの投稿を更新する必要があります。 (たとえば、100人のユーザーが投稿をお気に入りとして保存した場合、100個のデータに更新する必要があります。)

(そして、まったく同じように、トランザクションによってfavoritecountをインクリメントできるかどうかはわかりません。)

firebase.batch()を使えば、管理できると思います。しかし、私はそれが非効率的だと思います。

どちらの方法も完璧ではないようです。このケースのベストプラクティスを知っていますか?

8

配列または コレクショングループ の使用はどうですか?

解決策1:配列

posts
  -postID
   -title,content,author(userID),createdDate,favoriteCount
  -[favoriters(userID)]

これで、ユーザーのIDを「配列に含む」投稿をクエリすることで、ユーザーのお気に入りをクエリできます。大量のデータコピーを繰り返さずに、個々の投稿を変更することもできます。

ただし、このアプローチには限界があります。ドキュメントの最大サイズは1MiBです。ユーザーIDが4バイトであると仮定すると、ドキュメントには25万人以下のお気に入りを含めることができます。クライアントはまた、お気に入りを追加/削除するために、いくつかのO(N)処理を行う必要があります。

解決策2: コレクショングループ

posts
  -postID
   -title,content,author(userID),createdDate,favoriteCount
  -favoriters {collection}
   -userID

コレクショングループは、同じIDを持つすべてのコレクションで構成されます。デフォルトでは、クエリはデータベース内の単一のコレクションから結果を取得します。コレクショングループクエリを使用して、単一のコレクションからではなく、コレクショングループからドキュメントを取得します。

そのため、ユーザーのお気に入りの投稿を

db.collectionGroup("favoriters").whereEqualTo("userID", <userID>).get()

投稿をお気に入りに追加するには、

val postsRef = db.collection("posts")
posts.document(<postID>).collection("favoriters").add({ "userID", <userID> })
1
Gilbert

あなたの質問に対する直接の答えではないかもしれませんが、公式ドキュメントにはその例があります:

配列、リスト、およびセットの操作

概要:データをドキュメント内の配列のような構造で保存およびクエリします。

ユースケース:アプリで配列、リスト、セットなどの複雑なデータオブジェクトが必要な場合は、このソリューションで概説されているモデルに従ってください。たとえば、ブログアプリでは、関連する投稿のセットを作成したい場合があります。

https://firebase.google.com/docs/firestore/solutions/arrays

0
cashmash