2011-01-03 20 views
82
{ 

     "_id" : ObjectId("4d1cb5de451600000000497a"),   
     "name" : "dannie", 
     "interests" : [ 
      "guitar", 
      "programming",   
      "gadgets", 
      "reading" 
     ] 
} 

से ऊपर हटाने उदाहरण में, मान लें ऊपर दस्तावेज़ db.people संग्रह में है। के तीसरे तत्व को कैसे हटाएं सरणी अनुक्रमणिका?MongoDB में, कैसे आप एक सरणी तत्व अपने सूचकांक

संपादित करें:

यह मेरे वर्तमान समाधान है:

var interests = db.people.findOne({"name":"dannie"}).interests; 
interests.splice(2,1) 
db.people.update({"name":"dannie"}, {"$set" : {"interests" : interests}}); 

वहाँ एक और अधिक प्रत्यक्ष रास्ता नहीं है?

+0

https://docs.mongodb.org/manual/reference/operator/update/pull/ – userMod2

उत्तर

114

सरणी अनुक्रमणिका द्वारा खींच/निकालने का कोई सीधा तरीका नहीं है। वास्तव में, यह एक खुला मुद्दा http://jira.mongodb.org/browse/SERVER-1014 है, आप इसके लिए मतदान कर सकते हैं।

वैकल्पिक हल $ सेट किए बिना और फिर $ पुल उपयोग कर रहा है:

db.lists.update({}, {$unset : {"interests.3" : 1 }}) 
db.lists.update({}, {$pull : {"interests" : null}}) 

अद्यतन: टिप्पणियाँ इस दृष्टिकोण परमाणु नहीं है और कुछ दौड़ की स्थिति पैदा कर सकता है, तो अन्य ग्राहकों पढ़ सकते हैं और/या लिखने से कुछ में उल्लिखित दो संचालन के बीच। हम आपरेशन की जरूरत है परमाणु होने के लिए, हम कर सकते हैं:

  • दस्तावेज़ डेटाबेस
  • अद्यतन दस्तावेज़ से पढ़ें और डेटाबेस में दस्तावेज़ को बदलें सरणी
  • में आइटम को हटा दें। यह सुनिश्चित करने के दस्तावेज़ के बाद से हम इसे पढ़ा नहीं बदला है, हम अगर मौजूदा पैटर्न in the mongo docs
+27

यह एक डेढ़ साल हो गया है? क्या यह अभी भी मोंगोडब के साथ चीजों की स्थिति है? – Abe

+0

अगला उत्तर अधिक प्रत्यक्ष है और मेरे लिए काम किया है। हालांकि यह इंडेक्स द्वारा नहीं हटा रहा है, बल्कि मूल्य से हटा रहा है। – vish

+1

@ जेवियर - क्या यह समाधान आपको समस्याओं के लिए खुला नहीं करेगा यदि डीबी ने उस समय के बीच बदल दिया जब आपने इंडेक्स में स्थिति की गणना की थी, और जिस समय आपने अनसेट किया था? – UpTheCreek

18

वर्णित अद्यतन का उपयोग कर सकते आप एक सरणी में एक विशेष तत्व को हटाने के लिए update आपरेशन के $pull संशोधक का उपयोग कर सकते हैं।

db.people.update({"name":"dannie"}, {'$pull': {"interests": "guitar"}}) 

इसके अलावा, आप सभी घटनाओं को हटाने के लिए $pullAll उपयोग करने पर विचार हो सकता है: मामले में आप एक प्रश्न इस तरह दिखेगा प्रदान की है। आधिकारिक दस्तावेज़ीकरण पृष्ठ पर इसके बारे में अधिक जानकारी - http://www.mongodb.org/display/DOCS/Updating#Updating-%24pull

यह किसी तत्व को हटाने के लिए मानदंड के रूप में अनुक्रमणिका का उपयोग नहीं करता है, लेकिन फिर भी आपके जैसा मामलों में मदद कर सकता है। आईएमओ, सरणी के अंदर तत्वों को संबोधित करने के लिए इंडेक्स का उपयोग करना बहुत विश्वसनीय नहीं है क्योंकि मोंगोडब तत्वों के क्रम में संगत नहीं है जैसा कि मुझे पता है।

+5

उसका तत्व प्रश्न में एक सरणी है। इस मामले में मोंगो लगातार आदेश पर है। वास्तव में, सभी दस्तावेजों को वास्तव में संग्रह का आदेश दिया जाता है लेकिन कई ड्राइवर उन्हें इस तरह से संभाल नहीं पाते हैं। इस मामले को और जटिल बनाते हुए, यदि किसी दस्तावेज़ को अद्यतन ऑपरेशन के बाद स्थानांतरित किया जाना है (पैडिंग कारक से परे विकास के कारण) चाबियों का क्रम अचानक वर्णमाला बन जाता है (कवर के तहत, मुझे लगता है कि उन्हें उनके द्विआधारी मूल्य से क्रमबद्ध किया जाता है, यह संदेह है मेरे ज्ञान के आधार पर कि सरणी कुंजी के साथ बहुत अधिक मानक दस्तावेज़ हैं जो तारों के बजाय लगातार पूर्णांक हैं)। – marr75

+0

यह अनसेट + पुल की समस्याओं से बचाता है, लेकिन यह आवश्यक है कि आपके शब्दकोश का सख्ती से आदेश दिया जाए। अधिकांश भाषाओं में शब्दकोश अनियंत्रित होते हैं, इसलिए ऐसा करने के लिए दर्द हो सकता है। –

+0

@ marr75: क्या आपके पास कोई संदर्भ है? मोंगो दस्तावेजों को हमेशा आदेश बनाए रखना होता है, और अगर यह कभी भी उप-दस्तावेजों को फिर से व्यवस्थित करता है तो बहुत सी चीजें टूट जाएंगी। –

2

मैं सरणी में प्रत्येक उप-दस्तावेज़ के लिए एक GUID (मैं ऑब्जेक्ट आईडी का उपयोग करता हूं) फ़ील्ड, या स्वत: वृद्धिशील फ़ील्ड का उपयोग करने की अनुशंसा करता हूं।

इस GUID के साथ $ पुल जारी करना आसान है और सुनिश्चित करें कि सही व्यक्ति खींचा जाएगा। अन्य सरणी संचालन के लिए भी चला जाता है।

0

अनसेट (स्वीकृत उत्तर में) का उपयोग करने के बजाय, मैं इसे एक अद्वितीय मूल्य (यानी न्यूल नहीं) पर सेट करके और फिर तुरंत उस मान को खींचकर हल करता हूं। एक Asynch परिप्रेक्ष्य से थोड़ा सुरक्षित।

var update = {}; 
    var key = "ToBePulled_"+ new Date().toString(); 
    update['feedback.'+index] = key; 
    Venues.update(venueId, {$set: update}); 
    return Venues.update(venueId, {$pull: {feedback: key}}); 

उम्मीद है कि मोंगो शायद $ स्थिति संशोधक का विस्तार $ खींच के साथ-साथ $ धक्का का समर्थन करने के द्वारा इस संबोधित करेंगे,: यहाँ कोड है।

1

$ खींचने के बजाय हम अपने सूचकांक द्वारा सरणी में तत्वों को हटाने के लिए $ पॉप का उपयोग कर सकते हैं। लेकिन आपको इंडेक्स के आधार पर हटाने के लिए इंडेक्स स्थिति से 1 घटा देना चाहिए।

उदाहरण के लिए यदि आप सूचकांक 0 में तत्व, सूचकांक 1 के लिए आप 0 और इतने पर इस्तेमाल करना चाहिए आप -1 का उपयोग करना चाहिए निकालना चाहते हैं तो ...

क्वेरी निकालने में 3 तत्व (गैजेट):

db.people.update({"name":"dannie"}, {'$pop': {"interests": 1}})

संदर्भ के लिए

: https://docs.mongodb.com/manual/reference/operator/update/pop/

+0

लिंक किए गए दस्तावेज़ों के मुताबिक, '$ pop' केवल सरणी से पहले या अंतिम तत्व को हटा सकता है। इस उत्तर में क्वेरी तीसरे तत्व को नहीं हटाती है। –

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