java - फायरस्टार-एक फ़ीड की संरचना और सिस्टम का पालन कैसे करें




android firebase (4)

मैं अपने परीक्षण सोशल नेटवर्क ऐप के लिए Firebase realtime डेटाबेस का उपयोग कर रहा था जिसमें आप बस उन लोगों को पोस्ट कर सकते हैं जिन्हें आप अनुसरण करते हैं और प्राप्त कर सकते हैं। एक पारंपरिक सामाजिक नेटवर्क। मैंने अपने डेटाबेस को कुछ इस तरह संरचित किया-

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

मेरे पास एक और नोड "सामग्री" भी है जिसमें सिर्फ सभी उपयोगकर्ता पोस्ट की आईडी शामिल है। तो, अगर "ए" ने बी के सभी पोस्ट आईडी की तुलना में "बी" का पालन किया जहां ए की टाइमलाइन में जोड़ा गया। और अगर B ने इससे कुछ पोस्ट किया है तो इसके सभी फॉलोवर्स की टाइमलाइन में जोड़ा गया है।

अब यह रियलटाइम डेटाबेस के लिए मेरा समाधान था, लेकिन इसमें स्पष्ट रूप से कुछ मापनीयता मुद्दे हैं

  • अगर किसी के 10,000 फॉलोअर्स हैं तो एक नई पोस्ट को 10,000 फॉलोअर्स टाइमलाइन में जोड़ा गया।
  • अगर किसी के पास बड़ी मात्रा में पद हैं, तो हर नए अनुयायी को उसकी टाइमलाइन में सभी पद प्राप्त हैं।

ये कुछ समस्याएं थीं।

अब, मैं इस पूरे मामले को फायरस्टार पर स्थानांतरित करने के बारे में सोच रहा हूं क्योंकि इसका दावा "स्केलेबल" है। तो मुझे अपने डेटाबेस को कैसे तैयार करना चाहिए ताकि मैं रियलटाइम डेटाबेस में आने वाली समस्याओं को फायरस्टार में समाप्त कर सकूं।


आपको अनुयायियों के बीच संबंध रखने की आवश्यकता है:

Followers
-leading_id
-follower_id
-created_at

अगला, मुझे लगता है कि आपको समय सारणी की आवश्यकता नहीं है। जब आप एक फ़ीड खोलते हैं, तो सभी अनुयायियों को प्राप्त करें और उनके पदों के साथ जुड़ें, साथ ही आप अनुरोध में किसी प्रकार के आदेश और फ़िल्टर का उपयोग कर सकते हैं।

आपकी संरचना में पोस्टों के बारे में टाइमलाइन तालिका डुप्लिकेट जानकारी, मुझे लगता है कि यह डेटाबेस के लिए सामान्य नहीं है।


दो स्थितियां हैं

  1. आपके ऐप में उपयोगकर्ताओं के पास बहुत कम संख्या में अनुयायी हैं।

  2. आपके ऐप में उपयोगकर्ताओं के बड़ी संख्या में अनुयायी हैं। अगर हम फायरस्टार में किसी एकल डॉक्यूमेंट में एक ही सरणी में पूरे फॉलोअर्स स्टोर करने जा रहे हैं। फिर यह प्रति दस्तावेज 1 मिब की फायरस्टार सीमा को हिट करेगा।

  1. पहली स्थिति में, प्रत्येक उपयोगकर्ता को एक दस्तावेज़ रखना होगा जो एक ही दस्तावेज़ में एक ही सरणी में अनुयायियों की सूची संग्रहीत करता है। arrayUnion() और arrayRemove() का उपयोग करके अनुयायियों की सूची को कुशलता से प्रबंधित करना संभव है। और जब आप अपनी टाइमलाइन में कुछ पोस्ट करने जा रहे हैं तो आपको पोस्ट डॉक्यूमेंट में फॉलोअर्स की लिस्ट को जोड़ना होगा।

    और पोस्ट लाने के लिए नीचे दिए गए क्वेरी का उपयोग करें

    postCollectionRef.whereArrayContains("followers", userUid).orderBy("date");
  2. दूसरी स्थिति में, आपको केवल अनुसरणकर्ता दस्तावेज़ के आकार या गणना के आधार पर उपयोगकर्ता के दस्तावेज़ को तोड़ने की आवश्यकता है। सरणी के आकार को एक निश्चित आकार में पहुंचने के बाद अगले अनुयायी की आईडी को अगले दस्तावेज़ में जोड़ना होगा। और पहले दस्तावेज़ में फ़ील्ड "hasNext" रखना चाहिए, जो एक बूलियन मान संग्रहीत करता है। एक नया पोस्ट जोड़ते समय आपको पोस्ट दस्तावेज़ को डुप्लिकेट करना होगा और प्रत्येक दस्तावेज़ में अनुयायियों की सूची शामिल होगी जो पहले टूट जाती है। और हम वही क्वेरी कर सकते हैं जो ऊपर दस्तावेज़ लाने के लिए दी गई है।


मैं सुझाए गए समाधान के साथ थोड़ा संघर्ष कर रहा हूं, ज्यादातर तकनीकी अंतर के कारण, इसलिए मैंने एक और समाधान निकाला जो मेरे लिए काम करता है।

प्रत्येक उपयोगकर्ता के लिए मेरे पास सभी खातों के साथ एक दस्तावेज़ है जो वे अनुसरण करते हैं, लेकिन उन सभी खातों की एक सूची भी है जो उस उपयोगकर्ता का अनुसरण करते हैं।

जब एप्लिकेशन शुरू होता है, तो मुझे उन खातों की सूची मिलती है जो इस वर्तमान उपयोगकर्ता का अनुसरण करते हैं, और जब कोई उपयोगकर्ता एक पोस्ट करता है, तो पोस्ट ऑब्जेक्ट का हिस्सा उन सभी उपयोगकर्ताओं का सरणी होता है जो उनका अनुसरण करते हैं।

जब उपयोगकर्ता B चाहता है कि उसके द्वारा अनुसरण किए जा रहे लोगों के सभी पोस्ट प्राप्त कर लें, तो मैं केवल क्वेरी के लिए एक सरल विज्ञापन तैयार करता whereArrayContains("followers", currentUser.uid)

मुझे यह दृष्टिकोण पसंद है क्योंकि यह अभी भी मुझे किसी भी अन्य मापदंडों द्वारा परिणाम ऑर्डर करने की अनुमति देता है जो मुझे चाहिए।

पर आधारित:

  • 1mb प्रति दस्तावेज़, जो मैंने बनाया एक Google खोज द्वारा 1,048,576 अध्यायों को धारण करने के लिए लगता है।
  • यह तथ्य कि फायरस्टार ने यूआईडी का निर्माण किया, वह लगभग 28 वर्ण लंबा प्रतीत होता है।
  • ऑब्जेक्ट में बाकी जानकारी बहुत अधिक आकार नहीं लेती है।

यह दृष्टिकोण उन उपयोगकर्ताओं के लिए काम करना चाहिए जिनके पास लगभग 37,000 अनुयायी हैं।


मैंने आपके प्रश्न को थोड़ी देर बाद देखा है, लेकिन मैं आपको सर्वश्रेष्ठ डेटाबेस संरचना प्रदान करने का प्रयास करूंगा, जिसके बारे में मैं सोच सकता हूं। तो आशा है कि आपको यह उत्तर उपयोगी लगेगा।

मैं एक स्कीमा के बारे में सोच रहा हूं जिसमें users लिए तीन शीर्ष स्तर के संग्रह हैं users that a user is following और posts :

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 फॉलोअर्स टाइमलाइन में जोड़ा गया।

यह कोई समस्या नहीं होगी क्योंकि यही कारण है कि फायरस्टार में संग्रह मानसिक हैं। क्लाउड फायरस्टोर डेटाबेस के मॉडलिंग के आधिकारिक दस्तावेज के अनुसार:

क्लाउड फायरस्टार को छोटे दस्तावेजों के बड़े संग्रह को संग्रहीत करने के लिए अनुकूलित किया गया है।

यही कारण है कि मैंने userFollowing को संग्रह के रूप में जोड़ा है न कि एक साधारण वस्तु / मानचित्र के रूप में जो अन्य वस्तुओं को धारण कर सकता है। याद रखें, सीमा और कोटा के संबंध में आधिकारिक दस्तावेज के अनुसार दस्तावेज़ का अधिकतम आकार 1 MiB (1,048,576 bytes) । संग्रह के मामले में, एक संग्रह के नीचे दस्तावेजों की संख्या के बारे में कोई सीमा नहीं है। वास्तव में, इस तरह की संरचनाओं के लिए फायरस्टार को अनुकूलित किया गया है।

तो इस तरह से उन 10,000 अनुयायियों का होना, पूरी तरह से ठीक काम करेगा। इसके अलावा, आप डेटाबेस को इस तरह से क्वेरी कर सकते हैं जिसमें कहीं भी कुछ भी कॉपी करने की आवश्यकता नहीं होगी।

जैसा कि आप देख सकते हैं, डेटाबेस बहुत अधिक आप इसे बहुत सरल क्वेरी करने की अनुमति दे सकता है। आइए कुछ उदाहरण लेते हैं, लेकिन इससे पहले कि हम डेटाबेस से संबंध बनाएं और कोड की निम्नलिखित पंक्तियों का उपयोग करके उपयोगकर्ता का uid प्राप्त करें:

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

यदि आप उन सभी उपयोगकर्ताओं को प्राप्त करने के लिए डेटाबेस को क्वेरी करना चाहते हैं जो एक उपयोगकर्ता का अनुसरण कर रहा है, तो आप निम्नलिखित संदर्भ पर एक get() कॉल का उपयोग कर सकते हैं:

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

तो इस तरह से, आप सभी उपयोगकर्ता वस्तुओं को प्राप्त कर सकते हैं जो एक उपयोगकर्ता का अनुसरण कर रहा है। उनके यूआईडी होने से आप उनके सभी पोस्ट प्राप्त कर सकते हैं।

मान लें कि आप अपनी टाइमलाइन पर हर उपयोगकर्ता के नवीनतम तीन पोस्ट प्राप्त करना चाहते हैं। इस समस्या को हल करने के लिए महत्वपूर्ण है, जब बहुत बड़े डेटा सेट का उपयोग करते हुए डेटा को छोटी मात्रा में लोड करना है। मैंने अपने जवाब में इस post एक अनुशंसित तरीके से समझाया है जिसमें आप क्वेरी कर्सर को limit() विधि के साथ जोड़कर प्रश्नों को शांत कर सकते हैं। मैं आपको बेहतर समझ के लिए इस video पर एक नज़र डालने की सलाह देता हूं। तो हर उपयोगकर्ता के नवीनतम तीन पोस्ट प्राप्त करने के लिए, आपको इस समाधान का उपयोग करने पर विचार करना चाहिए। तो सबसे पहले आपको पहले 15 उपयोगकर्ता ऑब्जेक्ट प्राप्त करने की आवश्यकता है जो आप उनके अनुसरण कर रहे हैं और फिर उनके uid आधार पर, उनके नवीनतम तीन पोस्ट प्राप्त करने के लिए। एकल उपयोगकर्ता के नवीनतम तीन पोस्ट प्राप्त करने के लिए, कृपया निम्नलिखित प्रश्न का उपयोग करें:

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

जैसा कि आप नीचे स्क्रॉल कर रहे हैं, अन्य 15 उपयोगकर्ता ऑब्जेक्ट लोड करें और उनके नवीनतम तीन पोस्ट और इसी तरह प्राप्त करें। date अलावा आप अपनी post ऑब्जेक्ट में अन्य गुण भी जोड़ सकते हैं, जैसे लाइक, कमेंट, शेयर आदि।

अगर किसी के पास बड़ी मात्रा में पद हैं, तो हर नए अनुयायी को उसकी टाइमलाइन में सभी पद प्राप्त हैं।

बिल्कुल नहीं। ऐसा कुछ करने की जरूरत नहीं है। मैं पहले ही ऊपर बता चुका हूं कि क्यों।

20 मई, 2019 को संपादित करें:

ऑपरेशन को ऑप्टिमाइज़ करने का एक और उपाय जिसमें उपयोगकर्ता को अपने द्वारा अनुसरण किए जाने वाले सभी पोस्ट को देखना चाहिए, उन पोस्ट को संग्रहीत करना है जो उपयोगकर्ता को उस उपयोगकर्ता के लिए एक दस्तावेज़ में देखना चाहिए।

इसलिए यदि हम एक उदाहरण लेते हैं, तो मान लें कि facebook, आपके पास प्रत्येक उपयोगकर्ता के लिए facebook फीड वाला एक दस्तावेज होना चाहिए। हालांकि, अगर बहुत अधिक डेटा है जो एक एकल दस्तावेज़ ( 1 Mib ) को पकड़ सकता है, तो आपको उस डेटा को एक संग्रह में रखने की आवश्यकता है, जैसा कि ऊपर बताया गया है।








google-cloud-firestore