सबसे पहले 'उपयोगकर्ता वर्ग में शब्दकोश' एक अच्छा विचार नहीं है। क्यों? अतिरिक्त दर वस्तु जोड़ने के लिए सरणी में एक नया आइटम पुश करने की आवश्यकता होती है, जिसका अर्थ है कि पुरानी वस्तु को हटा दिया जाएगा, और इस प्रविष्टि को तथाकथित "दस्तावेज़ को स्थानांतरित करना कहा जाता है। ". दस्तावेज़ों को स्थानांतरित करना धीमा है और खाली स्थान का पुन:उपयोग करने में MongoDB इतना अच्छा नहीं है, इसलिए दस्तावेज़ों को बहुत अधिक इधर-उधर ले जाने से बड़ी मात्रा में खाली डेटा फ़ाइल ('MongoDB द डेफ़िनिटिव गाइड' पुस्तक में कुछ पाठ) हो सकती है।
फिर सही समाधान क्या है:मान लें कि आपके पास ब्लॉग नाम का एक संग्रह है, और आप अपने ब्लॉग पोस्ट के लिए एक रेटिंग समाधान लागू करना चाहते हैं, और इसके अलावा प्रत्येक उपयोगकर्ता-आधारित दर संचालन पर नज़र रखें।
ब्लॉग दस्तावेज़ के लिए स्कीमा इस प्रकार होगी:
{
_id : ....,
title: ....,
....
rateCount : 0,
rateValue : 0,
rateAverage: 0
}
आपको इस दस्तावेज़ स्कीमा के साथ एक और संग्रह (दरें) चाहिए:
{
_id: ....,
userId: ....,
postId:....,
value: ..., //1 to 5
date:....
}
और आपको इसके लिए एक उचित अनुक्रमणिका परिभाषित करने की आवश्यकता है:
db.Rates.ensureIndex({userId : 1, postId : 1})// very useful. it will result in a much faster search operation in case you want to check if a user has rated the post previously
जब कोई उपयोगकर्ता रेट करना चाहता है, तो सबसे पहले आपको यह जांचना होगा कि उपयोगकर्ता ने पोस्ट को रेट किया है या नहीं। मान लें कि उपयोगकर्ता 'user1'
है , तब क्वेरी होगी
var ratedBefore = db.Rates.find({userId : 'user1', postId : 'post1'}).count()
और ratedBefore
. के आधार पर , अगर !ratedBefore
फिर दर संग्रह में नया दर-दस्तावेज़ डालें और ब्लॉग स्थिति अपडेट करें, अन्यथा, उपयोगकर्ता को रेट करने की अनुमति नहीं है
if(!ratedBefore)
{
var postId = 'post1'; // this id sould be passed before by client driver
var userId = 'user1'; // this id sould be passed before by client driver
var rateValue = 1; // to 5
var rate =
{
userId: userId,
postId: postId,
value: rateValue,
date:new Date()
};
db.Rates.insert(rate);
db.Blog.update({"_id" : postId}, {$inc : {'rateCount' : 1, 'rateValue' : rateValue}});
}
फिर rateAverage
. का क्या होगा? ?मैं दृढ़ता से अनुशंसा करता हूं कि इसकी गणना rateCount
. के आधार पर की जाए और rateValue
क्लाइंट साइड पर, rateAverage
. को अपडेट करना आसान है mongoquery
. के साथ , लेकिन आपको ऐसा नहीं करना चाहिए। क्यों? इसका सरल उत्तर है:क्लाइंट के लिए इस तरह के कार्यों को संभालना बहुत आसान काम है और प्रत्येक ब्लॉग दस्तावेज़ पर औसत डालने के लिए एक अनावश्यक अपडेट ऑपरेशन की आवश्यकता होती है।
औसत क्वेरी की गणना इस प्रकार की जाएगी:
var blog = db.Blog.findOne({"_id" : "post1"});
var avg = blog.rateValue / blog.rateCount;
print(avg);
इस दृष्टिकोण के साथ आप मोंगोडब के साथ अधिकतम प्रदर्शन प्राप्त करेंगे, आपके पास उपयोगकर्ता, पोस्ट और दिनांक के आधार पर प्रत्येक दर का ट्रैक होगा।