2011-12-01 18 views
25

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

तो, { Price : 19.99 }

मुझे क्या करना db.collection.update({tag : "refurb"}, {$set {Price : Price * 0.50 }}, false, true);

यह किया या मैं मूल्य वापस ग्राहक के लिए पढ़ने के लिए है किया जा सकता है करना चाहते हैं को देखते हुए संशोधित करते हैं तो अद्यतन? मुझे लगता है कि प्रश्न का अद्यतन अद्यतन में किया जा सकता है, और क्या वे अद्यतन किए जा रहे दस्तावेज को संदर्भित कर सकते हैं।

+3

कृपया ध्यान दें कि मोंगो के आगामी संस्करण में, आप यह सब eval और डीबी किसी कीमत पर लगभग ताला लगा के बिना ऐसा कर सकते हैं । नए उत्तर को जांचें और स्वीकार कर सकते हैं, ताकि नए देव अप्रचलित जानकारी का उपयोग न करें। –

उत्तर

34

आप db.eval() के साथ सर्वर-साइड कोड चला सकते हैं।

db.eval(function() { 
    db.collection.find({tag : "refurb"}).forEach(function(e) { 
     e.Price = e.Price * 0.5; 
     db.collection.save(e); 
    }); 
}); 

नोट यह डीबी को अवरुद्ध करेगा, इसलिए खोज-अद्यतन ऑपरेशन जोड़ी करना बेहतर है।

देखें http://www.mongodb.org/display/DOCS/Server-side+Code+Execution

+0

धन्यवाद। क्या आप कह रहे हैं कि मुझे eval() का उपयोग करना चाहिए जैसा कि आपने दिखाया है, या ब्लॉकिंग से बचने के लिए इसे खोजने/अपडेट के साथ क्लाइंट पक्ष करना चाहिए? – Brad

+1

@ ब्रैड आपको इस विशेष अद्यतन ऑपरेशन की कुल लागत का मूल्यांकन करना चाहिए। यदि ऑपरेशन लंबा होने जा रहा है (संग्रह में कई दस्तावेज़ अपडेट किए जाएंगे) तो आपको कभी भी eval का उपयोग नहीं करना चाहिए। दस्तावेज़ को पहले पूछताछ करने के लिए कोई बड़ा ओवरहेड नहीं है और फिर इन-प्लेस अपडेट के बजाय इसे अपडेट करें। विशेष रूप से यदि आप बड़े दस्तावेज़ों के लिए पूछे गए फ़ील्ड को सीमित करते हैं और कवर इंडेक्स फीचर का उपयोग करते हैं (http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields#RetrievingaSubsetofFields-CoveredIndexes) – pingw33n

+1

कूल, धन्यवाद। मैं भी eval() sharding के साथ काम नहीं करता है, ताकि यह मेरे लिए लंबे समय तक नियमों के लिए नियम। नोलॉक एक दिलचस्प जोड़ है। – Brad

-1

खैर, यह सेट $ के रूप में एक परमाणु संचालन के साथ संभव है।

  • eval() समाधान pingw33n
  • द्वारा प्रस्तावित का उपयोग दस्तावेज़ आप वर्तमान मूल्य मिलता है और एक सेट
  • यदि आप के साथ इसे संशोधित करने के लिए संशोधित करना चाहते हैं पुनः प्राप्त:

    आप कई विकल्प हैं एक उच्च ऑपरेशन दर है, हो सकता है कि आप यह सुनिश्चित करना चाहें कि आपके मूल्य (पिछले समाधान का उपयोग करके) प्राप्त करने के दौरान दस्तावेज़ बदल नहीं गया है, तो हो सकता है कि आप एक खोज एंडमोडाइफ़ का उपयोग करना चाहें (this page देखें कि इसे कैसे करें) ऑपरेशन।

यह वास्तव में आपके संदर्भ पर निर्भर करता है: डीबी पर बहुत कम दबाव के साथ, मैं pingw33n के समाधान के लिए जाऊंगा। एक बहुत ही उच्च ऑपरेशन दर के साथ, मैं तीसरे समाधान का उपयोग करता हूं।

+0

धन्यवाद।मैं नहीं देखता कि कैसे ढूँढें AndModify एक अभिव्यक्ति का उपयोग करने की अनुमति देगा हालांकि, जो मेरा मुख्य लक्ष्य था। – Brad

+0

@Brad findAndModify अभिव्यक्ति का उपयोग करने की अनुमति देता है लेकिन यह दो चरण क्रिया करने की अनुमति देता है: पहले आइटम प्राप्त करें और फिर इसे अपडेट करें (अपने 50% की कमी के साथ) केवल – kamaradclimber

19

नए मोंगो 2.6.x में $mul operator है। यह निम्न वाक्यविन्यास के साथ संख्या के आधार पर फ़ील्ड के मान को गुणा करेगा।

{ 
    $mul: { field: <number> } 
} 

तो आपके मामले में आप निम्नलिखित करने की आवश्यकता होगी:

db.collection.update(
    { tag : "refurb"}, 
    { $mul: { Price : 0.5 } } 
); 
+1

पुनर्प्राप्त होने के बाद से यह नहीं बदला है, मेरे पास पर्याप्त उच्च नहीं है टिप्पणी करने के लिए प्रतिनिधि, अन्यथा यह उपरोक्त पद पर साल्वाडोर डाली द्वारा एक टिप्पणी होगी जिसने मेरी मदद की लेकिन गलत प्रारूप है। यह वास्तव में होना चाहिए: {$ mul: {field: }} नहीं {फ़ील्ड: {$ mul: }} – Wake

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