2011-05-22 14 views
15

मैं संदेशों के एक संग्रह है:क्या मोंगोडीबी में दो संग्रहों को परमाणु रूप से अपडेट करने का कोई तरीका है?

{ 
    userid: ObjectId 
    total: int 
    unread: int 
} 

जब मैं कुल से "संदेश" संग्रह, मैं भी कम करने के लिए की जरूरत है "संदेश को हटा दें:

{ 
    messageid: ObjectId 
    userid: ObjectId 
    message: string 
    isread: true|false 
} 

और संदेश का एक संग्रह प्रति उपयोगकर्ता मायने रखता है "गणना" संग्रह में, और सशर्त रूप से (यदि "message.isread" == false) "अपठित" फ़ील्ड भी कम करें।

इसके लिए मुझे पहले टीएच संदेश पुनर्प्राप्त करने की आवश्यकता है, इसके "आश्रय" फ़ील्ड को जांचें, और फिर गणनाओं को अपडेट करें। एक संभावना है कि संदेश को उन कार्रवाइयों के बीच पढ़ने के रूप में चिह्नित किया जाएगा, फिर मैं गलत तरीके से "अपठित" गणनाओं को कम कर दूंगा।

क्या एक शॉट में अन्य संग्रह के परिणामों के आधार पर एक संग्रह में सशर्त रूप से कुछ बदलने का कोई तरीका है?

उत्तर

11

वहाँ जवाब के बहुत सारे यहाँ हैं, लेकिन मैं कारतूस यहां के सभी में भरना चाहते हैं:

वहाँ किसी भी तरह से atomically है MongoDB में दो संग्रह अद्यतन करें?

नहीं। दो संग्रहों का परमाणु अद्यतन प्रभावी रूप से एक लेनदेन है। MongoDB संग्रहों में या यहां तक ​​कि संग्रह में लेनदेन का समर्थन नहीं करता है।

MongoDB several modifiers प्रदान करता है जो एक ही दस्तावेज़ पर परमाणु हैं।तो आप एक बार में कई अलग-अलग चर बढ़ा सकते हैं ($inc)। यद्यपि यहां कुछ सीमाएं हैं, आप एक ही संपत्ति पर दो अलग-अलग संचालन नहीं कर सकते हैं।

क्या एक शॉट में अन्य संग्रह के परिणामों के आधार पर एक संग्रह में सशर्त रूप से कुछ बदलने का कोई तरीका है?

सामान्य रूप से atomic updates पर कुछ दस्तावेज़ यहां दिए गए हैं। हालांकि, आपको वास्तव में एक कतार और two-phase commit का कुछ रूप है या आपको ट्रिगर की आवश्यकता है।

ट्रिगर्स के पास not yet been implemented है, इसलिए यह वास्तव में आपके मामले में कोई विकल्प नहीं है।

एक संभावना है कि संदेश उन कार्यों के बीच पढ़ने के रूप में चिह्नित किया जाएगा, तो मैं गलत तरीके से "अपठित" गणनाओं को कम कर दूंगा।

इस बिंदु पर, इस व्यवहार को कुछ स्तर की स्थिरता के साथ बनाने के लिए आपके पास कुछ अलग-अलग रणनीतियों हैं। स्पष्ट रूप से, आपके विवरण के आधार पर, आप एक साधारण कतार बनाने की जांच करना चाह सकते हैं जो आपके योग को अपडेट करता है।

0

आप एसक्यूएल में ट्रिगर के साथ ऐसा कर सकते हैं। लेकिन मोंगो में, कोई ट्रिगर नहीं है।

आप दस्तावेज़ में से एक पर कार्रवाई करने और SafeMode.True

की स्थापना तब यदि कोई त्रुटि तो दूसरा संग्रह को अद्यतन द्वारा कि संचालन पर LastErrorMessage के लिए देख सकते हैं।

वर्तमान में परमाणु तरीके से ऐसा करने का कोई तरीका नहीं है।

यदि वहां है, तो मैं अपने प्रोजेक्ट में उपयोग करता। मुझे उस कार्यक्षमता की भी आवश्यकता थी।

1

नहीं, दुर्भाग्य से यह संभव नहीं है। MongoDB केवल एक दस्तावेज़ के दायरे में atomic operations का समर्थन करता है। कई दस्तावेजों में एक लेनदेन ऑपरेशन करने का कोई तरीका नहीं है, भले ही वे एक ही संग्रह में हों।

4

आप एक ही पल में दो संग्रहों से दस्तावेज़ों को हटा नहीं सकते हैं। आप क्या कर सकते हैं किसी दस्तावेज़ को निकालने के लिए findAndModify() का उपयोग करें ताकि इसे हटाए जाने से पहले आपको इसकी सटीक स्थिति मिल सके। यह आपकी अपठित गिनती समस्या का ख्याल रखेगा।

1

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

वास्तव में, आपके कुल और अपठित फ़ील्ड बस कैश हैं। क्या आपको सचमुच इसकी जरूरत है ?

यहाँ एक ऐसी ही समस्या पर एक सवाल है: MongoDB: Calling Count() vs tracking counts in a collection

+0

यह मेरा प्रश्न भी था :) मेरी साइट तुलनात्मक रूप से उच्च भार होगी, और जब भी मुझे उनकी आवश्यकता होती है, मैं आंकड़ों को दोबारा नहीं जोड़ना चाहता, इसलिए मैं उस काउंटर संग्रह का उपयोग कर रहा हूं। – Andrey

+0

यदि आप पहले से ऐसा नहीं कर चुके हैं तो आपको इसे प्रोफ़ाइल करना चाहिए। – Maxence

+0

प्रोफाइलिंग के बिना भी, मैं कह सकता हूं कि कर्सर.count() हमेशा एक संख्या को पुनः प्राप्त करने से बहुत धीमा होगा, खासकर लाखों रिकॉर्ड के साथ सेट पर। – Andrey

संबंधित मुद्दे

 संबंधित मुद्दे