java - write - firestore set data




Firestore-如何構建訂閱源並遵循系統 (4)

我在我的測試社交網絡應用程序中使用Firebase實時數據庫,您可以在其中關注並接收您關注的人員的帖子。 傳統的社交網絡。 我將我的數據庫構造成這樣的東西 -

Users
--USER_ID_1
----name
----email
--USER_ID_2
----name
----email

Posts
--POST_ID_1
----image
----userid
----date
--POST_ID_2
----image
----userid
----date

Timeline
--User_ID_1
----POST_ID_2
------date
----POST_ID_1
------date

我還有另一個節點“內容”,它只包含所有用戶帖子的ID。 因此,如果“A”跟在“B”之後,那麼B的所有帖子ID都添加到A的時間軸。 如果B發布了一些內容,那麼它也會添加到其所有關注者的時間軸中。

現在這是我的實時數據庫解決方案,但它顯然存在一些可擴展性問題

  • 如果有人擁有10,000個關注者,則新帖子被添加到所有10,000個關注者的時間線中。
  • 如果有人擁有大量帖子,那麼每個新粉絲都會在他的時間軸中收到所有這些帖子。

這些都是一些問題。

現在,我正在考慮將整個事情轉移到firestore上,因為它聲稱是“可擴展的”。 那麼我應該如何構建我的數據庫,以便在firestore中消除我在實時數據庫中遇到的問題。


你需要保持關注者之間的關係:

Followers
-leading_id
-follower_id
-created_at

接下來,我認為你不需要時間表。 當您打開Feed時,請獲取所有關注者並加入他們的帖子,此外您還可以使用某種訂單並過濾請求。

在您的結構中,時間表表重複有關帖子的信息,我認為這對數據庫來說並不正常。


我一直在努力與她建議的解決方案,主要是由於技術差距,所以我想到另一個適合我的解決方案。

對於每個用戶,我都有一個包含他們所關注的所有帳戶的文檔,但也包含跟隨該用戶的所有帳戶的列表。

當應用程序啟動時,我會抓住當前用戶後面的帳戶列表,當用戶發帖時,post對象的一部分是跟隨它們的所有用戶的數組。

當用戶B想要得到他們所關注的人的所有帖子時,我只是在查詢中找到一個簡單的 whereArrayContains("followers", currentUser.uid)

我喜歡這種方法,因為它仍然允許我通過我想要的任何其他參數來排序結果。

基於:

  • 每個文件1mb,通過我搜索的谷歌搜索似乎擁有1,048,576個chaarecters。
  • Firestore生成的UID似乎長約28個字符。
  • 對像中的其餘信息不會佔用太多大小。

這種方法適用於擁有最多約37,000名粉絲的用戶。


我稍後見過您的問題,但我也會嘗試為您提供我能想到的最佳數據庫結構。 所以希望你會發現這個答案很有用。

我正在考慮一個架構,其中有三個頂級集合供 usersusers that a user is followingposts users that a user is following

Firestore-root
   |
   --- users (collection)
   |     |
   |     --- uid (documents)
   |          |
   |          --- name: "User Name"
   |          |
   |          --- email: "[email protected]"
   |
   --- following (collection)
   |      |
   |      --- uid (document)
   |           |
   |           --- userFollowing (collection)
   |                 |
   |                 --- uid (documents)
   |                 |
   |                 --- uid (documents)
   |
   --- posts (collection)
         |
         --- uid (documents)
              |
              --- userPosts (collection)
                    |
                    --- postId (documents)
                    |     |
                    |     --- title: "Post Title"
                    |     |
                    |     --- date: September 03, 2018 at 6:16:58 PM UTC+3
                    |
                    --- postId (documents)
                          |
                          --- title: "Post Title"
                          |
                          --- date: September 03, 2018 at 6:16:58 PM UTC+3

如果有人擁有10,000個關注者,則新帖子被添加到所有10,000個關注者的時間線中。

這根本不是問題,因為這就是Firestore中收藏的原因。 根據 Cloud Firestore數據庫建模 的官方文檔:

Cloud Firestore針對存儲大量小型文檔進行了優化。

這就是我將 userFollowing 添加為集合而不是作為可以容納其他對象的簡單對象/地圖的原因。 請記住,根據有關 限制和配額 的官方文檔,文檔的最大大小為 1 MiB (1,048,576 bytes) 。 在收集的情況下,對集合下面的文檔數量沒有限制。 事實上,對於這種結構,Firestore進行了優化。

因此,以這種方式擁有這10,000名粉絲,將完美無缺。 此外,您可以以不需要在任何地方復制任何內容的方式查詢數據庫。

正如您所看到的,數據庫幾乎是非 規範化的, 允許您非常簡單地查詢它。 讓我們舉一些例子,但在讓我們創建一個與數據庫的連接並使用以下代碼行獲取用戶的 uid 之前:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();

如果要查詢數據庫以獲取用戶正在關注的所有用戶,可以對以下引用使用 get() 調用:

CollectionReference userFollowingRef = rootRef.collection("following/" + uid + "/userFollowing");

因此,通過這種方式,您可以獲得用戶正在關注的所有用戶對象。 有了他們的uid,你可以簡單地得到他們的所有帖子。

假設您希望在時間軸上了解每個用戶的最新三篇帖子。 當使用非常大的數據集時,解決此問題的關鍵是以較小的塊加載數據。 我在本文的回答中解釋了一種推薦的方法,您可以通過將查詢游標與 limit() 方法相結合來對查詢進行分頁。 我還建議您看一下這個 video 以便更好地理解。 因此,要獲得每個用戶的最新三篇帖子,您應該考慮使用此解決方案。 首先,您需要獲取您正在關注的前15個用戶對象,然後根據他們的 uid 獲取最新的三個帖子。 要獲取單個用戶的最新三篇帖子,請使用以下查詢:

Query query = rootRef.collection("posts/" + uid + "/userPosts").orderBy("date", Query.Direction.DESCENDING)).limit(3);

在向下滾動時,加載其他15個用戶對象並獲取最新的三個帖子,依此類推。 除了 date 之外,您還可以向 post 對象添加其他屬性,例如喜歡,評論,分享等的數量。

如果有人擁有大量帖子,那麼每個新粉絲都會在他的時間軸中收到所有這些帖子。

沒門。 沒有必要做這樣的事情。 我已經解釋了為什麼。

編輯2019年5月20日:

優化用戶應該看到他所關注的每個人的所有最近帖子的操作的另一個解決方案是存儲用戶應該在該用戶的文檔中看到的帖子。

因此,如果我們舉個例子,讓我們說facebook,你需要有一個包含每個用戶的facebook feed的文檔。 但是,如果單個文檔可以容納的數據太多( 1 Mib ),則需要將該數據放入集合中,如上所述。


有兩種情況

  1. 您應用中的用戶擁有少量關注者。

  2. 您應用中的用戶擁有大量粉絲。 如果我們要將整個關注者存儲在firestore中的單個文檔中的單個數組中。 然後它將達到每個文檔1 MiB的火焰庫限制。

  1. 在第一種情況下,每個用戶必須保存一個文檔,該文檔將關注者列表存儲在單個陣列中的單個文檔中。 通過使用 arrayUnion()arrayRemove() ,可以有效地管理關注者列表。 當您要在時間軸中發佈內容時,您必須在帖子文檔中添加關注者列表。

    並使用下面給出的查詢來獲取帖子

    postCollectionRef.whereArrayContains("followers", userUid).orderBy("date");
  2. 在第二種情況下,您只需根據關注者數組的大小或數量打破用戶關注文檔。 在將數組的大小達到固定大小後,下一個關注者的id必須添加到下一個文檔中。 第一個文檔必須保留字段“hasNext”,它存儲一個布爾值。 添加新帖子時,您必須複製帖子文檔,每個文檔都包含先前打破的關注者列表。 我們可以使用上面給出的相同查詢來獲取文檔。





google-cloud-firestore