2012-02-10 19 views
17

मैं किसी मौजूदा फ़ील्ड के मान पर सेट किए गए नए फ़ील्ड के मान के साथ संग्रह में एक नया फ़ील्ड जोड़ना चाहता हूं।मौजूदा फ़ील्ड के मान के साथ संग्रह में एक नया फ़ील्ड जोड़ें

विशेष रूप से, मैं इस से जाने के लिए करना चाहते हैं:

# db.foo.findOne() 
    { 
     "_id"  : ObjectId("4f25c828eb60261eab000000"), 
     "created" : ISODate("2012-01-29T16:28:56.232Z"), 
     "..."  : ... 
    } 
इस के लिए

:

# db.foo.findOne() 
    { 
     "_id"  : ObjectId("4f25c828eb60261eab000000"), 
     "created" : ISODate("2012-01-29T16:28:56.232Z"), 
     "event_ts" : ISODate("2012-01-29T16:28:56.232Z"), #same as created 
     "..."  : ... 
    } 

(इस संग्रह यह सब अजीब अतिरेक नहीं होगा में नई दस्तावेजों, लेकिन मैं चाहता हूँ मेरे मौजूदा दस्तावेजों के लिए ऐसा करने के लिए)

+0

तो यह एक बार की बात है जो आपको करने की ज़रूरत है? – ggreiner

+0

सही, इस डेटा को तैयार करने के लिए केवल एक बार ऐसा करने की आवश्यकता है – Purrell

उत्तर

38
function addEventTsField(){ 
    db.foo.find().forEach(function(doc){ 
     db.foo.update({_id:doc._id}, {$set:{"event_ts":doc.created}}); 
    }); 
} 

रन: (आपके मामले में _id, और created अगर प्रदर्शन एक मुद्दा है कि आप केवल specific fields लोड कर सकते हैं):

addEventTsField(); 
+2

हालांकि परमाणु ऑपरेशन नहीं है। बीच में बीच डेटा बदलने की संभावना के साथ ये दो अलग-अलग ऑपरेशन हैं। (हालांकि वह शायद अपने मामले में सुरक्षित है क्योंकि ऐसा लगता है कि वह इसे एक बार ऑफ़लाइन कर रहा है) – UpTheCreek

2

नहीं, यह संभव नहीं है। केवल दो कदम thats तुम शायद है पता:

  1. लोड दस्तावेज़, पढ़ने के क्षेत्र।
  2. दस्तावेज़ के परमाणु अद्यतन (सेट event_ts लोड created फ़ील्ड का उपयोग करके) कंसोल से
+0

db.foo.find() .Each() के साथ कुछ भी नहीं। – Purrell

+1

@Purrell: 'forEach' वास्तव में सभी पाए गए दस्तावेज़ों को लोड करता है, और यह दो चरणों का अद्यतन बन जाता है ... –

-1

चूंकि आपका कोड पहले से ही जानता है कि event_ts को कैसे संभालना है, आपको डेटा कॉपी करने की आवश्यकता क्यों है? आप क्षेत्र के बजाय नाम बदल सकते हैं:

{ $rename : { old_field_name : new_field_name } } 

देखें http://www.mongodb.org/display/DOCS/Updating

+4

आप एक धारणा बना रहे हैं, दस्तावेजों में 'बनाई गई' की भी आवश्यकता नहीं है। – Purrell

-1

तो यह करने के लिए, अपनी कोई बड़ी समस्या नहीं एक बार बात है। "Db.foo.find();" जैसे क्वेरी चलाएं अपने मोंगो शेल्फ में और टेक्स्टपैड या सब्लिमे टेक्स्ट जैसे संपादक को पूरा आउटपुट पेस्ट करें, कॉलम ब्लॉक करें (उत्कृष्ट पाठ में यह Ctrl + scroll wheel & ड्रैग पर क्लिक करें), पेस्ट करें जो इसे किसी अन्य फ़ील्ड तक बढ़ाएगा, नवनाम का नाम बदलें पेस्ट किए गए कॉलम के रूप में आप इसे चाहते हैं, एक बार किया गया है, "bb.foo.insert ({" और "$" के रूप में "}" के साथ पूरे समूह को "^" के रूप में संपादित करने के लिए एक रेगेक्स करें; "

यह निम्न चरणों की तरह है। {: मूल्य, 'field2': मान 2, 'फ़ील्ड 3': 'फ़ील्ड 1' VALUE4}

  1. आप की तरह उत्पादन चिपकाया;
    1. अंतिम सेट की प्रतिलिपि बनाएँ और संपादक कॉलम ब्लॉक {'field1': मान, 'field2': value2, 'field3': value4} का उपयोग करके विस्तार करें;
    2. अब उचित शब्दों को मोंगो db.foo.insert ({'field1': value, 'field2': value2, 'field3': value4} के लिए कमांड की तरह दिखने के लिए उचित शब्दों को सम्मिलित करें;
    3. अब उन सभी को कॉपी करें और इसे अपने मोंगो खोल में पेस्ट करें जो आपके लिए पूरी चीज करेगा जैसा आप चाहते हैं। इसे एक बार परीक्षण करें और संग्रह को साफ करने के बाद पूरी चीज को फिर से करें अन्यथा यह डुप्लिकेट डालेगा। आउटपुट में "_id" फ़ील्ड को भी हटा दें क्योंकि जब आप दोबारा डालने का प्रयास करेंगे तो यह संघर्ष करेगा !!

अब, अपने संपादक में हर एक पंक्ति एक वैध मोंगो आदेश है कि अपने खोल करने के लिए चिपकाया जा सकता है अपने संग्रह में एक नया दस्तावेज़ डालने को दर्शाता है। तो इसे एक बार जांचें और यह ठीक काम करता है, अपने पूरे संग्रह को "db.foo.remove ({}) जैसे साफ़ करें;" और पूरे आदेश को संपादक से पेस्ट करें जो इसे एक ग्रिफ़ी में करेगा।

जब आप पहली बार प्रयास करते हैं तो यह मुश्किल हो सकता है, लेकिन अगर आपको यह सही लगता है कि जब भी आप चाहें तो काम करने के लिए यह एक आसान काम होगा .... !!

+0

यह उत्तर भी समझ में नहीं आता है, क्योंकि यह बहुत त्रुटि-प्रवण है, स्वचालित नहीं किया जा सकता है, परीक्षण नहीं किया जा सकता है, स्क्रिप्ट नहीं किया जा सकता है ... आप कभी भी इस ऑपरेशन को एक संपादक में क्यों करना चाहते हैं, जब इसे सरल कार्य और प्रत्येक() के साथ आसानी से किया जा सकता है? –

+0

इसके अलावा -1 क्योंकि इसे ऑपरेशन के बीच में 'db.foo.remove ({})' की आवश्यकता होती है, जो मौजूदा डेटा को अभी भी वहां होने की उम्मीद कर सकती है। – David

+0

प्रश्न उस समय के साथ पोस्ट किया गया था जब यह एक समय पर काम करता है। साथ ही, संपादक में इसे करने से इसे संपादित करने की आवश्यकता होती है, किस पर टिप्पणी की जानी चाहिए या क्या निकाला जाना चाहिए। निस्संदेह फोरैच का उपयोग करने का समाधान बेहतर है, यह इतना बुरा नहीं है क्योंकि जब हम परीक्षण के बीच में होते हैं तो हमें डेटा को अक्सर सम्मिलित करने की आवश्यकता होती है, उन्हें हटा दें, वहां कुछ बदलावों के साथ उन्हें फिर से जोड़ें इत्यादि, जब आप केवल वही स्क्रिप्ट फ़ाइल कमांड लाइन में चलाते हैं तो इसे स्वचालित भी किया जा सकता है। – Param

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