mongodb - किसी अन्य क्षेत्र के मूल्य का उपयोग करके मोंगोडीबी फ़ील्ड अपडेट करें




mongodb-query aggregation-framework (4)

~ 150_000 रिकॉर्ड्स के लिए एक फ़ील्ड को दूसरे में कॉपी करने के लिए हम यहां आए हैं। इसमें लगभग 6 मिनट लग गए, लेकिन यह अभी भी काफी कम संसाधन संसाधन है जो कि तत्काल मात्रा में रूबी ऑब्जेक्ट्स को तुरंत चालू करने और फिर से चालू करने के लिए होता।

js_query = %({
  $or : [
    {
      'settings.mobile_notifications' : { $exists : false },
      'settings.mobile_admin_notifications' : { $exists : false }
    }
  ]
})

js_for_each = %(function(user) {
  if (!user.settings.hasOwnProperty('mobile_notifications')) {
    user.settings.mobile_notifications = user.settings.email_notifications;
  }
  if (!user.settings.hasOwnProperty('mobile_admin_notifications')) {
    user.settings.mobile_admin_notifications = user.settings.email_admin_notifications;
  }
  db.users.save(user);
})

js = "db.users.find(#{js_query}).forEach(#{js_for_each});"
Mongoid::Sessions.default.command('$eval' => js)

MongoDB में, क्या किसी अन्य फ़ील्ड से मूल्य का उपयोग करके किसी फ़ील्ड के मान को अपडेट करना संभव है? समकक्ष एसक्यूएल कुछ ऐसा होगा:

UPDATE Person SET Name = FirstName + ' ' + LastName

और मोंगोडीबी छद्म कोड होगा:

db.person.update( {}, { $set : { name : firstName + ' ' + lastName } );

आप दस्तावेज को एक अद्यतन (अभी तक) में संदर्भित नहीं कर सकते हैं। आपको दस्तावेज़ों के माध्यम से पुन: प्रयास करना होगा और फ़ंक्शन का उपयोग करके प्रत्येक दस्तावेज़ को अपडेट करना होगा। उदाहरण के लिए यह उत्तर देखें, या सर्वर-साइड eval() लिए यह एक देखें।


उच्च गतिविधि वाला डेटाबेस के लिए, आप उन मुद्दों पर जा सकते हैं जहां आपके अपडेट सक्रिय रूप से रिकॉर्ड बदलते हैं और इस कारण से मैं स्नैपशॉट () का उपयोग करने की सलाह देता हूं

db.person.find().snapshot().forEach( function (hombre) {
    hombre.name = hombre.firstName + ' ' + hombre.lastName; 
    db.person.save(hombre); 
});

http://docs.mongodb.org/manual/reference/method/cursor.snapshot/


ऐसा करने का सबसे अच्छा तरीका हमारे नए क्षेत्र की गणना करने के लिए एकत्रीकरण ढांचे का उपयोग करना है।

मोंगोडीबी 3.4

सबसे आसान समाधान मोंगोडीबी 3.4 में $addFields और $out एग्रीगेशन पाइपलाइन ऑपरेटरों का उपयोग कर रहा है।

db.collection.aggregate(
    [
        { "$addFields": { 
            "name": { "$concat": [ "$firstName", " ", "$lastName" ] } 
        }},
        { "$out": "collection" }
    ]
)

ध्यान दें कि यह आपके संग्रह को अपडेट नहीं करता है बल्कि इसके बजाय मौजूदा संग्रह को प्रतिस्थापित करता है या एक नया बनाता है। इसके अलावा अपडेट ऑपरेशंस के लिए "टाइप कास्टिंग" की आवश्यकता होती है, आपको क्लाइंट साइड प्रसंस्करण की आवश्यकता होगी, और ऑपरेशन के आधार पर, आपको .aggreate() विधि के बजाय .aggreate() विधि का उपयोग करने की आवश्यकता हो सकती है।

मोंगोडीबी 3.2 और 3.0

जिस तरह से हम यह करते हैं, हमारे दस्तावेज़ों में $project और समेकित स्ट्रिंग को वापस करने के लिए $concat स्ट्रिंग एग्रीगेशन ऑपरेटर का उपयोग करता है। हम वहां से, फिर आप कर्सर को फिर से सक्रिय करते हैं और अधिकतम दक्षता के लिए थोक संचालन का उपयोग करके अपने दस्तावेज़ों में नया फ़ील्ड जोड़ने के लिए $set अपडेट ऑपरेटर का उपयोग करते हैं।

एकत्रीकरण क्वेरी:

var cursor = db.collection.aggregate([ 
    { "$project":  { 
        "name": { "$concat": [ "$firstName", " ", "$lastName" ] } 
    }}
])

मोंगोडीबी 3.2 या नया

इससे, आपको bulkWrite विधि का उपयोग करने की आवश्यकता है।

var requests = [];
cursor.forEach(document => { 
    requests.push( { 
        'updateOne': {
            'filter': { '_id': document._id },
            'update': { '$set': { 'name': document.name } }
        }
    });
    if (requests.length === 500) {
        //Execute per 500 operations and re-init
        db.collection.bulkWrite(requests);
        requests = [];
    }
});

if(requests.length > 0) {
     db.collection.bulkWrite(requests);
}

MongoDB 2.6 और 3.0

इस संस्करण से आपको अब बहिष्कृत Bulk एपीआई और इसके संबंधित तरीकों का उपयोग करने की आवश्यकता है।

var bulk = db.collection.initializeUnorderedBulkOp();
var count = 0;

cursor.snapshot().forEach(function(document) { 
    bulk.find({ '_id': document._id }).updateOne( {
        '$set': { 'name': document.name }
    });
    count++;
    if(count%500 === 0) {
        // Excecute per 500 operations and re-init
        bulk.execute();
        bulk = db.collection.initializeUnorderedBulkOp();
    }
})

// clean up queues
if(count > 0) {
    bulk.execute();
}

मोंगोडीबी 2.4

cursor["result"].forEach(function(document) {
    db.collection.update(
        { "_id": document._id }, 
        { "$set": { "name": document.name } }
    );
})




aggregation-framework