2012-12-28 18 views
10

डालें मैं मोनो डीबी में अपरर्ट का उपयोग करने की कोशिश कर रहा हूं ताकि दस्तावेज़ में एक फ़ील्ड अपडेट किया जा सके या बहुत से फ़ील्ड के साथ एक नया दस्तावेज़ डालें। समस्या यह है कि मुझे लगता है कि मोंगोडीबी या तो हर क्षेत्र को प्रतिस्थापित करता है या अपने अपरिवर्तनीय संचालन में खेतों का एक सबसेट डालता है, यानी यह वास्तव में अपडेट करना चाहता है उससे अधिक फ़ील्ड सम्मिलित नहीं कर सकता है।Mongodb अपरर्ट केवल चयनित फ़ील्ड अपडेट करें, लेकिन सभी

  • मैं एक ही अनूठा मूल्य
  • तो एक दस्तावेज पहले से मौजूद है के लिए क्वेरी, केवल एक टाइमस्टैम्प मूल्य (इसे कहते देता है 'lastseen') के लिए अद्यतन किया जाता है:

    मुझे क्या करना चाहते हैं निम्नलिखित है एक नया मान

  • यदि कोई दस्तावेज़ मौजूद नहीं है, तो मैं इसे विभिन्न कुंजी/मूल्य जोड़े की एक लंबी सूची के साथ जोड़ूंगा जो इसके जीवनकाल के शेष के लिए स्थैतिक रहना चाहिए।

चलें चित्रण करते हैं:

यह उदाहरण हैं मेरी समझ से 'lastseen' तिथि को अपडेट करता है, तो 'नाम' पाया जाता है, लेकिन अगर 'नाम' नहीं मिला है यह केवल 'नाम' + 'lastseen सम्मिलित हैं '।

db.somecollection.update({name: "some name"},{ $set: {"lastseen": "2012-12-28"}}, {upsert:true}) 

अगर मैं दूसरा तर्क के लिए और अधिक क्षेत्रों (कुंजी/मान जोड़े) जोड़ा गया है और $ सेट ड्रॉप, तो हर क्षेत्र अद्यतन पर प्रतिस्थापित किया जाएगा, लेकिन डालने पर वांछित प्रभाव होगा। क्या डालने के दौरान केवल $ डालने या संचालन करने के समान कुछ भी है?

तो मुझे लगता है कि मैं केवल निम्न में से एक प्राप्त कर सकते हैं:

  • अपडेट ही व्यवहार है, लेकिन केवल वांछित क्षेत्रों के सबसेट के साथ एक दस्तावेज सम्मिलित करता है, तो दस्तावेज़
  • मौजूद नहीं है होगा
  • सही सम्मिलित व्यवहार, लेकिन यदि दस्तावेज़ पहले से मौजूद है तो सभी मौजूदा फ़ील्ड को ओवरराइट कर देगा

क्या मेरी समझ सही है? यदि हां, तो क्या एक ही ऑपरेशन के साथ हल करना संभव है?

+1

वहाँ एक कारण है कि इन कुंजी-मान जोड़ों Upsert की खोज खंड में नहीं किया जा सकता है है? – Sammaye

+0

कारण यह है कि केवल एक फ़ील्ड है जिसे मैं उस बिंदु के मूल्य को जानता हूं। मैं नहीं चाहता कि क्वेरी 0 हिट लौटाए, यदि फ़ील्ड का सटीक कॉम्बो मेल नहीं खाता है। एकमात्र फ़ील्ड जो मुझे पता है कि यह तय करेगा कि यह एक नया डालने या अपडेट है या नहीं। – agnsaft

उत्तर

27

MongoDB 2,4 $setOnInsert

db.somecollection.update(
    {name: "some name"}, 
    { 
     $set: { 
      "lastseen": "2012-12-28" 
     }, 
     $setOnInsert: { 
      "firstseen": <TIMESTAMP> # set on insert, not on update 
     } 
    }, 
    {upsert:true} 
) 
8

इस (https://jira.mongodb.org/browse/SERVER-340) के लिए एक सुविधा अनुरोध है जो 2.3 में हल किया गया है। विषम रिलीज वास्तव में देव रिलीज हैं इसलिए यह 2.4 स्थिर में होगा।

तो वर्तमान स्थिर संस्करणों में अभी तक ऐसा करने का कोई वास्तविक तरीका नहीं है। मुझे डर है कि एकमात्र तरीका वास्तव में 3 सशर्त प्रश्नों को एटीएम करना है: पंक्ति को जांचने के लिए 1, फिर if या तो डालने या अपडेट करने के लिए।

मुझे लगता है कि अगर आपको यहां लॉक के साथ वास्तविक समस्याएं हैं तो आप इस समारोह को एकमात्र जेएस के साथ कर सकते हैं लेकिन यह बुरा है हालांकि यह इस अद्यतन को एक थ्रेड पर लॉक कर देगा।

+0

धन्यवाद दोस्त। मैं वास्तव में ऐसी जानकारी देखने के लिए जिरा में खोज कर रहा था, लेकिन स्पष्ट रूप से मैंने उसे याद किया है। – agnsaft

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