MongoDB
 sql >> डेटाबेस >  >> NoSQL >> MongoDB

mongodb $addToSet एक गैर-सरणी फ़ील्ड में जब upsert पर अपडेट किया जाता है

आप यहां जो करने की कोशिश कर रहे हैं वह केवल एक सरणी में एक नया आइटम जोड़ना है जहां आइटम मौजूद नहीं है और जहां यह मौजूद नहीं है वहां एक नया दस्तावेज़ भी बनाएं। आप $addToSet . चुनें क्योंकि आप चाहते हैं कि आइटम अद्वितीय हों, लेकिन वास्तव में आप वास्तव में उन्हें केवल "a" द्वारा अद्वितीय बनाना चाहते हैं।

तो $addToset ऐसा नहीं करेंगे, और आपको मौजूद तत्व को "परीक्षण" करने की आवश्यकता है। लेकिन यहां असली समस्या यह है कि ऐसा करना और एक ही समय में "अपरर्ट" करना दोनों संभव नहीं है। तर्क काम नहीं कर सकता क्योंकि एक नया दस्तावेज़ तब बनाया जाएगा जब सरणी तत्व नहीं मिला था, बजाय इसके कि आप जैसे सरणी तत्व को जोड़ना चाहते हैं।

$addToSet . के रूप में डिज़ाइन द्वारा वर्तमान संचालन त्रुटियां किसी सरणी को "बनाने" के लिए उपयोग नहीं किया जा सकता है, लेकिन केवल मौजूदा सरणी में सदस्यों को "जोड़ने" के लिए उपयोग किया जा सकता है। लेकिन जैसा कि पहले ही कहा जा चुका है, आपको तर्क हासिल करने में अन्य समस्याएं हैं।

यहां आपको जो चाहिए वह अद्यतन संचालन का एक क्रम है जो प्रत्येक अपनी अपेक्षित कार्रवाई करने के लिए "कोशिश" करता है। यह केवल कई कथनों के साथ किया जा सकता है:

// attempt "upsert" where document does not exist
// do not alter the document if this is an update
db.test.update(
    { "name": "abc" },
    { "$setOnInsert": { "config": [{ "a": 1, "b": 2 }] }},
    { "upsert": true }
)

// $push the element where "a": 1 does not exist
db.test.update(
    { "name": "abc", "config.a": { "$ne": 1 } },
    { "$push": { "config": { "a": 1, "b": 2 } }}
)

// $set the element where "a": 1 does exist
db.test.update(
    { "name": "abc", "config.a": 1 },
    { "$set": { "config.$.b": 2 } }
)

पहले पुनरावृत्ति पर पहला कथन दस्तावेज़ को "अपरर्ट" करेगा और वस्तुओं के साथ सरणी बनाएगा। दूसरा कथन दस्तावेज़ से मेल नहीं खाएगा क्योंकि "ए" तत्व में वह मान है जो निर्दिष्ट किया गया था। तीसरा स्टेटमेंट दस्तावेज़ से मेल खाएगा लेकिन यह इसे राइट ऑपरेशन में नहीं बदलेगा क्योंकि मान नहीं बदले हैं।

अगर आप अब इनपुट को "b": 3 . में बदलते हैं आपको अलग-अलग प्रतिक्रियाएं मिलती हैं लेकिन वांछित परिणाम:

db.test.update(
    { "name": "abc" },
    { "$setOnInsert": { "config": [{ "a": 1, "b": 3 }] }},
    { "upsert": true }
)

db.test.update(
    { "name": "abc", "config.a": { "$ne": 1 } },
    { "$push": { "config": { "a": 1, "b": 3 } }}
)

db.test.update(
    { "name": "abc", "config.a": 1 },
    { "$set": { "config.$.b": 3 } }
)

तो अब पहला स्टेटमेंट "name": "abc" . के साथ एक डॉक्यूमेंट से मेल खाता है लेकिन कुछ भी नहीं करता है क्योंकि केवल वैध संचालन "सम्मिलित करें" पर हैं। दूसरा कथन मेल नहीं खाता क्योंकि "ए" शर्त से मेल खाता है। तीसरा स्टेटमेंट "ए" के मान से मेल खाता है और मिलान किए गए तत्व में "बी" को वांछित मान में बदल देता है।

इसके बाद "ए" को दूसरे मान में बदलना जो सरणी में मौजूद नहीं है, 1 और 3 दोनों को कुछ भी नहीं करने की अनुमति देता है लेकिन दूसरा कथन सामग्री को उनकी "ए" कुंजी द्वारा अद्वितीय रखते हुए सरणी में एक और सदस्य जोड़ता है।

साथ ही मौजूदा डेटा में कोई बदलाव नहीं किए जाने के साथ एक स्टेटमेंट सबमिट करने से निश्चित रूप से एक प्रतिक्रिया मिलेगी जो कहती है कि सभी खातों में कुछ भी नहीं बदला है।

इस तरह आप अपना ऑपरेशन करते हैं। आप इसे "आदेशित" थोक के साथ कर सकते हैं संचालन ताकि संशोधित या बनाए गए वैध प्रतिक्रिया के साथ सर्वर से केवल एक ही अनुरोध और प्रतिक्रिया हो।



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. pymongo में find_one का उपयोग करके नवीनतम रिकॉर्ड कैसे प्राप्त करें

  2. मोंगोडब में नेस्टेड सरणियों को अद्यतन करना

  3. MongoDB में दिनांक को कैसे प्रारूपित करें

  4. MongoDB नेस्टेड सरणी में फ़ील्ड अपडेट कर रहा है

  5. Mongodb C# ड्राइवर असमर्थित फ़िल्टर त्रुटि विशिष्ट linq विधेय के साथ