आपके पास मूल रूप से 3 मामले हैं:
- पुस्तक और समीक्षा दोनों मौजूद हैं। यह एक साधारण
$set
है - पुस्तक मौजूद है लेकिन समीक्षा नहीं। इसके लिए
$push
. की आवश्यकता है - पुस्तक मौजूद नहीं है। इसके लिए
{upsert:1}
की आवश्यकता है और एक$setOnInsert
मैं विफलता के मामले में डेटा अखंडता से समझौता किए बिना इनमें से किन्हीं दो को एकजुट करने का कोई तरीका नहीं खोज पाया (याद रखें कि MongoDB में परमाणु लेनदेन नहीं है)।
तो मेरे सबसे अच्छा विचार निम्नलिखित है:
// Case 1:
db.books.update({isbn:'1234567890',
review: { $elemMatch: {userID: '01234'}}},
{$set: {'review.$.rating': NEW_RATING}}
)
// Case 2:
db.books.update({isbn:'1234567890',
review: { $not: { $elemMatch: {userID: '01234'}}}},
{$push: {review: {rating: NEW_RATING, userID:'01234'}}}
)
// Case 3:
db.books.update({isbn:'1234567890'},
{$setOnInsert: {review: [{rating: NEW_RATING, userID:'01234'}]}},
{upsert:1}
)
आप उन तीन अपडेट को रॉ में आँख बंद करके चला सकते हैं क्योंकि उनके बीच कोई ओवरलैपिंग केस नहीं है। बात की खूबसूरती यह है कि ये सभी ऑपरेशन हैं idempotent
. तो आप उन्हें एक या कई बार लागू कर सकते हैं और हमेशा एक ही परिणाम प्राप्त कर सकते हैं। विफलता के मामले में यह विशेष रूप से महत्वपूर्ण है। इसके अलावा, आपके डीबी के असंगत होने या मौजूदा . को ढीला करने का कोई तरीका नहीं है विफलता के मामले में डेटा। सबसे खराब, समीक्षा नहीं है अद्यतन किया गया। अंत में यह चाहिए समवर्ती अद्यतनों के मामले में भी डेटा स्थिरता की गारंटी देता है (यानी:उस स्थिति में, एक अद्यतन दूसरे को अधिलेखित कर देगा, लेकिन आपके पास एक ही पुस्तक के लिए दो दस्तावेज़ या एक ही पुस्तक के लिए एक ही उपयोगकर्ता की दो समीक्षाएँ नहीं होनी चाहिए)।
उस बाद के बिंदु की पुष्टि करनी होगी क्योंकि यहाँ देर हो चुकी है इसलिए मेरा विश्लेषण कुछ संदिग्ध हो सकता है।
अंतिम नोट के रूप में, यदि आप MongoDB और अपने ऐप के बीच राउंड-ट्रिप की संख्या को कम करना चाहते हैं, तो आप update
डेटाबेस कमांड
आपको कई अपडेट को एक कमांड में लपेटने की अनुमति देता है।