मुख्य सामग्री पर जाएँ

ब्लॉगिंग ऐप्स के लिए MongoDB डेटा मॉडलिंग गाइड

कंटेंट मैनेजमेंट सिस्टम (CMS) या ब्लॉग ऐप डिज़ाइन करते समय नेस्टेड डॉक्यूमेंट्स सहित कुछ डेटा मॉडलिंग संभावनाओं के बारे में जानें।
· 7 मि॰ पढ़ें

AI के साथ खोजें

तो आप अपना खुद का कंटेंट मैनेजमेंट सिस्टम (CMS), जिसे कभी-कभी ब्लॉग भी कहा जाता है, बनाना चाहते हैं? यह डेटाबेस का उपयोग करना सीखते समय एक क्लासिक उदाहरण है, चाहे वह रिलेशनल डेटाबेस मैनेजमेंट सिस्टम (RDBMS) हो या NoSQL डेटाबेस, क्योंकि यह संभावित रूप से बड़े डेटा और उसमें मौजूद रिश्तों को एक्सप्लोर करता है। ब्लॉगिंग ऐप का उदाहरण अन्य डेटा मॉडलिंग आवश्यकताओं के लिए भी अच्छी तरह काम करता है।

इस लेख में, हम MongoDB में अपने NoSQL डॉक्यूमेंट्स को डिज़ाइन करते समय क्या करें और क्या न करें, इसका पता लगाएंगे। हालांकि, हम वास्तव में कोई ब्लॉगिंग ऐप विकसित नहीं करेंगे, केवल डेटा के दृष्टिकोण से चीजें देखेंगे।

ब्लॉगिंग ऐप के घटक

ब्लॉग के लिए डॉक्यूमेंट मॉडल डिज़ाइन करने का प्रयास करने से पहले, एक कदम पीछे हटना और सोचना अच्छा है कि किन-किन घटकों से जुड़ा डेटा हो सकता है।

एक सामान्य ब्लॉग में निम्नलिखित सुविधाएँ हो सकती हैं:

  • कई उपयोगकर्ता या लेखक
  • किसी भी एक लेखक के लिए कई ब्लॉग पोस्ट
  • किसी भी एक ब्लॉग पोस्ट पर कई टिप्पणियाँ

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

जो आप कर सकते हैं, लेकिन नहीं करना चाहिए

ऊपर दी गई सुविधाओं को देखकर आपका पहला विचार हर बुलेट आइटम को उसका अपना डॉक्यूमेंट मानने का हो सकता है। यह वही सामान्य तरीका है जिसे आप Postgres जैसे रिलेशनल डेटाबेस में अपनाते हैं। MongoDB में, यह कुछ इस तरह दिख सकता है:

{
	"_id": "author-1",
	"name": "Nic Raboy",
	"description": "I'm some dude named Nic."
}

ऊपर दिया गया एक लेखक का बहुत संक्षिप्त प्रतिनिधित्व हो सकता है। बेशक, आपके पास email जैसे कई अन्य फ़ील्ड हो सकते हैं, लेकिन यहाँ वह वास्तव में महत्वपूर्ण नहीं है।

फिर, ब्लॉग पोस्ट के लिए हमारे पास निम्नलिखित हो सकता है:

{
	"_id": "blog-1",
	"author_id": "author-1",
	"title": "MongoDB is Awesome!",
	"content": "This is some blog content..."
}

पिछले की तरह ही, ब्लॉग डॉक्यूमेंट में tags और जो भी आप सोच सकें जैसे अन्य फ़ील्ड हो सकते हैं। यहाँ बड़ी बात यह है कि इसमें दोनों डॉक्यूमेंट्स के बीच एक id रेफरेंस है। इस पर आगे बात करेंगे।

इस परिदृश्य में अंतिम डॉक्यूमेंट मॉडल टिप्पणियों के आसपास होगा:

{
	"_id": "comment-1",
	"blog_id": "blog-1",
	"username": "Anonymous User",
	"content": "Hey great article, it really helped a lot!"
}

फिर से, इस परिदृश्य में टिप्पणी डॉक्यूमेंट में टिप्पणी डॉक्यूमेंट और ब्लॉग डॉक्यूमेंट के बीच एक id वैल्यू पर आधारित रेफरेंस रिलेशनशिप है। यह सब एक रिलेशनल डेटाबेस में बहुत आम है, और सच यह है कि यह MongoDB में भी ठीक काम करेगा। हालाँकि, यह आपको सबसे अच्छा MongoDB अनुभव नहीं देगा।

MongoDB में ऐसा न करने का एक कारण प्रदर्शन है।

इन तीनों डॉक्यूमेंट्स को जोड़ने के लिए, आप एग्रिगेशन पाइपलाइन में $lookup ऑपरेशन का उपयोग करना चाहेंगे। ये $lookup ऑपरेशन सस्ते नहीं होते और जैसे-जैसे आपका डेटाबेस स्केल करता है, आपके प्रदर्शन पर नकारात्मक प्रभाव डाल सकते हैं, खासकर जब आपके पाइपलाइन में एक से अधिक $lookup ऑपरेशन हों।

MongoDB में काम पूरा करने के बेहतर तरीके हैं।

डेटा मॉडलिंग के लिए एक बेहतर, MongoDB-अनुकूल दृष्टिकोण

MongoDB के पहले नियमों में से एक है कि जो डेटा साथ में एक्सेस किया जाता है, उसे साथ में ही स्टोर किया जाना चाहिए। प्रत्येक फीचर को अलग डॉक्यूमेंट या कलेक्शन में स्टोर करना इस नियम को तोड़ता है क्योंकि अब हम उपयोगकर्ता को दिखाए जाने वाले डेटा के लिए एकल फ़ेच ऑपरेशन नहीं कर रहे हैं।

आइए समस्या पर दोबारा नज़र डालते हैं और अपने ब्लॉग के लिए डॉक्यूमेंट्स को इस तरह मॉडल करते हैं:

{
	"_id": "author-1",
	"name": "Nic Raboy",
	"description": "I'm some dude named Nic.",
	"posts": [
		{
			"title": "MongoDB is Awesome!",
			"content": "This is some blog content...",
			"comments": [
				{
					"username": "Anonymous User",
					"content": "Hey great article, it really helped a lot!"
				}
			]
		}
	]
}

ठीक है, तो ऊपर दिए गए मॉडल में MongoDB के प्रमुख नियमों में से एक पूरा होता है। हमारे पास एक सिंगल डॉक्यूमेंट है जो नेस्टिंग का उपयोग करके लेखक के साथ सभी ब्लॉग पोस्ट और सभी टिप्पणियाँ स्टोर करता है।

हालाँकि यह काम कर सकता है, लेकिन अपने ब्लॉगिंग ऐप के डॉक्यूमेंट्स को इस तरह मॉडल करना शायद अच्छा विचार नहीं है।

MongoDB में डॉक्यूमेंट साइज की सीमाएँ होती हैं, और जब आपके डॉक्यूमेंट्स में अनबाउंडेड एरेज़ होते हैं, तो आप उन सीमाओं को पार करने का जोखिम उठाते हैं। यह तो अलग, जैसे-जैसे एरे बड़े होते जाते हैं, आप प्रदर्शन संबंधी समस्याओं से भी जूझ सकते हैं। इस मामले में, हमारे पास ब्लॉग पोस्ट की असीमित संख्या और प्रत्येक ब्लॉग पोस्ट पर असीमित संख्या में टिप्पणियाँ हो सकती हैं। किसी बिंदु पर यह गड़बड़ हो जाएगा।

इस उदाहरण में जो बेहतर काम कर सकता है, वह इन दोनों रणनीतियों का मिश्रण है।

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

{
	"_id": "blog-1",
	"author": {
		"_id": "author-1",
		"name": "Nic Raboy",
	},
	"title": "MongoDB is Awesome!",
	"content": "This is some blog content...",
	"comments": [
		{
			"username": "Anonymous User",
			"content": "Hey great article, it really helped a lot!"
		}
	]
}

इस उदाहरण में हमारा दूसरा डॉक्यूमेंट अब भी लेखक की जानकारी के लिए मूल डॉक्यूमेंट होगा:

{
	"_id": "author-1",
	"name": "Nic Raboy",
	"description": "I'm some dude named Nic."
}

हमें पता है कि ब्लॉग लेख दिखाते समय लेखक की कुछ जानकारी शामिल होनी चाहिए, लेकिन हमें आवश्यक रूप से सारी जानकारी की ज़रूरत नहीं है। हम आवश्यक लेखक जानकारी को _id के साथ ब्लॉग पोस्ट के अंदर एम्बेड कर सकते हैं, और यदि उपयोगकर्ता लेखक के बारे में अधिक जानना चाहता है, तो वह आपके एप्लिकेशन में आगे जा सकता है। $lookup ऑपरेशन हर बार नहीं होता, जिससे प्रदर्शन में सुधार होता है।

अब, हमारे सामने समस्या है कि किसी भी दिए गए ब्लॉग लेख के लिए संभावित रूप से अनंत टिप्पणियाँ वर्तमान में एक एरे के रूप में जुड़ी हुई हैं।

इसे संभालने के कुछ तरीके हैं और अंततः यह आप पर निर्भर करता है:

  • आप साधारण तरीका अपना सकते हैं और उन्हें एक एरे के रूप में रख सकते हैं, जो शायद अच्छा विचार नहीं है।
  • आप टिप्पणियों को मूल डिज़ाइन में वापस ले जा सकते हैं—प्रत्येक डॉक्यूमेंट में एक टिप्पणी—सभी में ब्लॉग लेख के लिए एक रेफरेंस id के साथ, और उन्हें शामिल करने के लिए $lookup ऑपरेशन का उपयोग कर सकते हैं।
  • आप एक आर्काइवल रणनीति अपना सकते हैं—ब्लॉग लेख के भीतर एक एरे में टिप्पणियों की एक निश्चित संख्या स्टोर करें और साथ ही प्रत्येक के लिए अलग टिप्पणी डॉक्यूमेंट बनाएँ—ताकि ज़रूरत पड़ने पर ही अतिरिक्त टिप्पणियों के लिए क्वेरी करनी पड़े।
  • आप बकेटिंग पैटर्न को एक्सप्लोर कर सकते हैं, जिसमें टिप्पणियों को प्रत्येक डॉक्यूमेंट में लगभग 100 टिप्पणियों के "बकेट्स" में समूहित किया जाता है, और एक समय में जितने कमेंट बकेट्स की ज़रूरत हो उतने क्वेरी किए जाते हैं। बकेटिंग डॉक्यूमेंट साइज लिमिट से बचाती है और पेजिनेशन में भी मदद करती है। आप इस दृष्टिकोण में blog_id पर इंडेक्स बनाकर प्रदर्शन को और बढ़ा सकते हैं, ताकि किसी भी विशेष ब्लॉग लेख के लिए टिप्पणियाँ जल्दी से प्राप्त की जा सकें। इंडेक्सिंग पर अधिक जानकारी MongoDB दस्तावेज़ीकरण में पाई जा सकती है।
  • मिश्रण, मिलान, और भी...

बकेटिंग पैटर्न के मामले में, आपकी टिप्पणी संबंधी डॉक्यूमेंट्स कुछ इस तरह दिख सकते हैं:

{
	"_id": "comment-bucket-1",
	"blog_id": "blog-1",
	"comments": [
		{
			"username": "Anonymous User",
			"content": "Hey great article, it really helped a lot!"
		},
		// More comments here...
	],
	"comment_count": 57
}

इस परिदृश्य में, जैसे ही नई टिप्पणियाँ बनती हैं, आप ऐसा बकेट क्वेरी करते हैं जो भरा न हो। आप नई टिप्पणी को एरे में पुश करते हैं और काउंट वैल्यू बढ़ाते हैं। जबकि इस रणनीति में बकेट्स को मेंटेन करने के लिए एप्लिकेशन-स्तरीय लॉजिक पर अधिक निर्भरता होती है, यह बेहतर प्रदर्शन देगी। यदि आपके ब्लॉग में इनफिनिट स्क्रॉल मैकेनिज़्म है, तो और भी अच्छा, क्योंकि तब आप बकेट्स के माध्यम से बेहतर पेजिनेशन कर सकते हैं।

हालाँकि यह इस विशेष लेख के दायरे से बाहर है, लेकिन यदि आप यह समझना चाहते हैं कि नई टिप्पणी जोड़ने में क्या लगता है, तो आप टिप्पणी बकेट्स कलेक्शन को (नीचे दिए गए उदाहरण क्वेरी देखें) ऐसे बकेट्स के लिए फ़िल्टर करेंगे जो blog_id से मेल खाते हों और जिनका comment_count आपके चुने हुए मान से कम हो।

मैच होने पर, आप अपने अपडेट मानदंड में $push ऑपरेटर और अपनी टिप्पणी की गिनती बढ़ाने के लिए $inc ऑपरेटर का उपयोग करेंगे। यह सब एक ही ऑपरेशन में किया जा सकता है, और यदि आप upsert फ्लैग का उपयोग करते हैं, तो आप नया टिप्पणी बकेट बना सकते हैं यदि कोई ऐसा बकेट पहले से मौजूद नहीं है जो आपके मानदंडों से मेल खाता हो।

अपडेट क्वेरी का उदाहरण: 

db.commentBuckets.updateOne(
  { blog_id: "blog-1", comment_count: { $lt: 100 } },
  { $push: { comments: newComment }, $inc: { comment_count: 1 } },
  { upsert: true }
)

निष्कर्ष

भले ही यह कहना अच्छा लगे कि आपको अपने ब्लॉग से जुड़ी हर चीज़ को एक सिंगल नेस्टेड डॉक्यूमेंट में स्टोर करना चाहिए, लेकिन शायद यह अच्छा विचार नहीं होगा। उसी तरह, ऐसा डेटा मॉडल लागू करना जो रिलेशनल डेटाबेस में अच्छा करता हो, लेकिन आवश्यक रूप से MongoDB जैसे डॉक्यूमेंट डेटाबेस में नहीं—यह भी शायद अच्छा विचार नहीं होगा।

MongoDB के साथ, आप सर्वोत्तम संभव प्रदर्शन पाने के लिए अपने रेफरेंस्ड रिलेशनशिप्स को यथासंभव कम रखना चाहेंगे।

जैसे-जैसे आप स्केल करते हैं, निम्नलिखित बातों का ध्यान रखें:

  • यदि आप भारी मात्रा में टिप्पणियों की उम्मीद करते हैं, तो बकेट पैटर्न या उसके साथ आंशिक एम्बेडिंग के किसी संयोजन पर विचार करें।
  • आपकी पेजिनेशन आवश्यकताएँ क्या हैं?
  • अपने एप्लिकेशन में क्वेरी की योजना के आधार पर अपनी कलेक्शंस को इंडेक्स करें।

दोहराने के लिए, सोचें कि आप अपने फ्रंटएंड में ब्लॉग डेटा कैसे प्रस्तुत करेंगे। क्या आपको वास्तव में अनुरोध के साथ लेखक की सारी जानकारी चाहिए या उसका कुछ हिस्सा पर्याप्त है? क्या आप वास्तव में अपने ब्लॉग लेख के साथ दस लाख टिप्पणियाँ लोड करना चाहते हैं या थोड़ी-सी पर्याप्त हैं? जब आप वास्तव में इस पर विचार करेंगे, तो आप यह देखकर हैरान होंगे कि आपको कितने जॉइन ऑपरेशन की ज़रूरत नहीं है।

यदि आप MongoDB में नए हैं, तो मैं Introduction to MongoDB in Python कोर्स देखने की सलाह देता हूँ।

FAQs

क्या मैं अपने ब्लॉग ऐप का डेटा मॉडल रिलेशनल डेटाबेस से MongoDB में ट्रांसफर कर सकता/सकती हूँ?

आप id रेफरेंस के साथ फ्लैट डॉक्यूमेंट्स बना सकते हैं और यह काम करेगा, लेकिन आप MongoDB से मिलने वाले अधिकतम प्रदर्शन का लाभ नहीं उठा पाएँगे।

सब कुछ एक ही डॉक्यूमेंट में स्टोर क्यों न करें?

MongoDB में साइज लिमिट्स हैं और जब आपके पास अनबाउंडेड एरेज़ होते हैं, तो आप आसानी से उन सीमाओं तक पहुँच सकते हैं।

बकेट पैटर्न का ज़िक्र किया गया था, लेकिन क्या और भी हैं?

अन्य पैटर्न भी हो सकते हैं जो काम करें, लेकिन बड़े एरेज़ के मामले में बकेट पैटर्न एक अच्छा विकल्प है।

MongoDB के डॉक्यूमेंट साइज लिमिट्स क्या हैं?

MongoDB डॉक्यूमेंट्स का अधिकतम आकार 16MB है।

नेस्टेड डेटा के अपडेट (जैसे, किसी टिप्पणी को एडिट करना) कैसे संभालें?

एम्बेडेड डेटा के लिए, आप $set जैसे अपडेट ऑपरेटर्स का उपयोग कर सकते हैं, और बकेटेड टिप्पणियों के लिए, आप बकेट खोजकर उसके भीतर विशेष टिप्पणी को अपडेट कर सकते हैं।

Nic Raboy

लेखक

Nic Raboy

निक रैबॉय MongoDB में डेवलपर रिलेशंस लीड हैं, जहाँ वे Python, Java, C# और PHP डेवलपर्स की एक टीम का नेतृत्व करते हैं जो ऐसा शानदार कंटेंट बनाते हैं जिससे डेवलपर्स अपने प्रोजेक्ट्स में MongoDB को सफलतापूर्वक शामिल कर सकें। उन्हें Golang और JavaScript का अनुभव है और वे प्रायः अपने विकास से जुड़ी अनेक यात्राओं के बारे में लिखते हैं।

विषय