मुझे और मेरे सहयोगियों को एक समाधान मिला। हम इसे तीन चरण आरंभीकरण . कह सकते हैं .
याद रखें कि MongoDB एकल दस्तावेज़ पर संचालन की परमाणुता की गारंटी देता है। इस तथ्य को ध्यान में रखते हुए हम निम्नलिखित तरीके से काम कर सकते हैं:
- दस्तावेज़ को अद्यतन करने का प्रयास करें, काउंटरों को एक निर्दिष्ट समय खंड पर ठीक से बढ़ाते हुए। कोई अपर्ट न करें, बस पुराने जमाने का अपडेट ऑपरेशन करें। याद रखें कि अपडेट स्टेटमेंट का निष्पादन लिखित दस्तावेजों की संख्या लौटाता है। यदि लिखे गए दस्तावेज़ों की संख्या शून्य से अधिक है, तो आपका काम हो गया।
- यदि अद्यतन द्वारा लिखे गए दस्तावेज़ों की संख्या शून्य है, तो इसका मतलब है कि अद्यतन करने के लिए संबंधित दस्तावेज़ अभी तक संग्रह में मौजूद नहीं है। निर्दिष्ट टैग के लिए संपूर्ण दस्तावेज़ सम्मिलित करने का प्रयास करें। सभी काउंटरों (फ़ील्ड मान) को शून्य पर रखें। साथ ही एक इन्सर्ट स्टेटमेंट का निष्पादन लिखित दस्तावेजों की संख्या लौटाता है। अगर यह शून्य लौटाता है या अपवाद फेंकता है, तो कोई बात नहीं:इसका मतलब है कि किसी अन्य प्रक्रिया ने पहले ही उसी टैग के लिए दस्तावेज़ सम्मिलित कर लिया था।
- उपरोक्त अपडेट को फिर से निष्पादित करें।
कोड निम्न कोड स्निपेट जैसा कुछ दिखना चाहिए।
// Firt of all, try the update
var result = db.test.update(
{timestamp_minute: ISODate("2013-10-10T23:06:00.000Z"), type: “memory_used”},
{$inc: {"values.39": 1}},
{upsert: false}
);
// If the update do not succeed, then try to insert the document
if (result.nModified === 0) {
try {
db.test.insert(/* Put here the whole document */);
} catch (err) {
console.log(err);
}
// Here we are sure that the document exists.
// Retry to execute the update statement
db.test.update(/* Same update as above */);
}
उपरोक्त प्रक्रिया काम करती है यदि एक पूर्व शर्त रखती है:_id
मूल्य दस्तावेज़ में अन्य क्षेत्रों से प्राप्त किया जाना चाहिए। हमारे उदाहरण में, _id
मान होगा '2013-10-10T23:06:00.000Z-memory_used
. केवल इस तकनीक का उपयोग करके, बिंदु 2 पर सम्मिलित करना ठीक से विफल हो जाएगा।