Mongoose (mongodb) बैच डालें?


114

क्या नेवला v3.6 + अब समर्थन बैच आवेषण? मैंने कुछ मिनटों के लिए खोज की है, लेकिन इस क्वेरी से मेल खाने वाली कोई भी चीज़ कुछ साल पुरानी है और इसका उत्तर एक असमान संख्या थी।

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

भविष्य के संदर्भ के लिए, उत्तर का उपयोग करना है Model.create()create()किसी सरणी को इसके पहले तर्क के रूप में स्वीकार करता है, इसलिए आप अपने दस्तावेज़ों को एक सरणी के रूप में सम्मिलित करने के लिए पास कर सकते हैं।

Model.create () प्रलेखन देखें


पिछले प्रश्न का उत्तर देखें ।
जॉनीएचके

धन्यवाद। यही मैंने पोस्ट करने के बाद ढूंढना समाप्त किया।
उपर्युक्त

@ उपसर्ग कृपया एक उत्तर के रूप में अपना संपादन जोड़ें और अपने प्रश्न को हल करने के लिए इसे स्वीकार करें।
फिलिप डुपनोविक


Model.create () धीमा है और यदि आप बड़ी संख्या में दस्तावेज़ सम्मिलित करने पर विचार कर रहे हैं, तो इसके बजाय इस दृष्टिकोण को लेना बेहतर है ।
लुसियो पाइवा

जवाबों:


162

Model.create () बनाम Model.collection.insert (): एक तेज़ तरीका

Model.create()आवेषण करने का एक बुरा तरीका है यदि आप एक बहुत बड़े थोक के साथ काम कर रहे हैं। यह बहुत धीमी गति से होगा । उस मामले में आपको उपयोग करना चाहिए Model.collection.insert, जो बेहतर प्रदर्शन करता है । थोक के आकार पर निर्भर करता है, Model.create()यहां तक ​​कि दुर्घटना होगी! लाख दस्तावेजों के साथ कोशिश की, कोई भाग्य नहीं। इसके इस्तेमाल में Model.collection.insertकुछ ही सेकंड लगे।

Model.collection.insert(docs, options, callback)
  • docs डाला जाने वाला दस्तावेज़ों का सरणी है;
  • optionsएक वैकल्पिक कॉन्फ़िगरेशन ऑब्जेक्ट है - डॉक्स देखें
  • callback(err, docs)सभी दस्तावेज़ सहेजे जाने या त्रुटि होने के बाद कॉल किया जाएगा। सफलता पर, डॉक्स निरंतर दस्तावेजों का एक सरणी है।

जैसा कि Mongoose के लेखक यहाँ बताते हैं , यह विधि किसी भी सत्यापन प्रक्रियाओं को दरकिनार कर देगी और सीधे Mongo ड्राइवर को एक्सेस करेगी। यह एक ऐसा व्यापार-व्यापार है जो आपको बड़ी मात्रा में डेटा को संभालने के बाद से करना पड़ता है, अन्यथा आप इसे अपने डेटाबेस में डालने में सक्षम नहीं होंगे (याद रखें कि हम यहां सैकड़ों हजारों दस्तावेज़ों की बात कर रहे हैं)।

एक सरल उदाहरण

var Potato = mongoose.model('Potato', PotatoSchema);

var potatoBag = [/* a humongous amount of potato objects */];

Potato.collection.insert(potatoBag, onInsert);

function onInsert(err, docs) {
    if (err) {
        // TODO: handle error
    } else {
        console.info('%d potatoes were successfully stored.', docs.length);
    }
}

अपडेट 2019-06-22 : हालांकि insert()अभी भी बस ठीक इस्तेमाल किया जा सकता है, यह इसके पक्ष में पदावनत किया गया है insertMany()। पैरामीटर बिल्कुल समान हैं, इसलिए आप इसे ड्रॉप-इन प्रतिस्थापन के रूप में उपयोग कर सकते हैं और सब कुछ ठीक काम करना चाहिए (ठीक है, वापसी मूल्य थोड़ा अलग है, लेकिन आप शायद वैसे भी इसका उपयोग नहीं कर रहे हैं)।

संदर्भ


1
group.google.com/forum/# ​​.topic/mongoose-orm/IkPmvcd0kds यह सब वास्तव में कहते हैं।
आर्केल्डन

कृपया मानगो के साथ उदाहरण दें।
स्टीव के।

15
चूंकि Model.collectionमोंगो चालक के माध्यम से सीधे जाता है, आप सत्यापन और हुक सहित सभी स्वच्छ मानगो सामान खो देते हैं। सिर्फ मन में रखने वाली कुछ बातें। Model.createहुक खो देता है, लेकिन फिर भी सत्यापन के माध्यम से चला जाता है। यदि आप यह सब चाहते हैं, तो आपको new MyModel()
इट्रेट

1
@ पियर-ल्यूकग्रेन्ड्रे आप बिलकुल सही हैं, लेकिन एक बार आपको डेटा की विनम्र राशि से निपटना शुरू करना होगा।
लुसियो पाइवा

1
नए पाठकों से सावधान रहें: "संस्करण 2.6 में परिवर्तित: सम्मिलित () एक वस्तु देता है जिसमें ऑपरेशन की स्थिति होती है"। और कोई डॉक्स नहीं।
मार्क नी

117

Mongoose 4.4.0 अब बल्क इंसर्ट का समर्थन करता है

Mongoose 4.4.0 मॉडल विधि के साथ --true-- बल्क इंसर्ट करता है .insertMany()। यह .create()एक ऐरे के साथ लूपिंग या इसे प्रदान करने की तुलना में तेज़ है ।

उपयोग:

var rawDocuments = [/* ... */];

Book.insertMany(rawDocuments)
    .then(function(mongooseDocuments) {
         /* ... */
    })
    .catch(function(err) {
        /* Error handling */
    });

या

Book.insertMany(rawDocuments, function (err, mongooseDocuments) { /* Your callback function... */ });

आप इसे ट्रैक कर सकते हैं:


2
इस समय, यह विधि विकल्पों का समर्थन नहीं करती है।
अमरी

जवाब के लिए धन्यवाद। किसी भी विचार कच्चे की जगह क्या होना चाहिए? मैंने इसे Json ऑब्जेक्ट्स की एक सरणी के साथ आज़माया है और इसमें जो कुछ भी डाला है वह सिर्फ उनकी ID थी। :(
ओन्डरेज टोकर

4
यह कैसे अलग है bulkWrite? यहां देखें: stackoverflow.com/questions/38742475/…
Ondrej Tokar

InsertMany मेरे लिए काम नहीं करता है। मुझे ए fatal error allocation failed। लेकिन अगर मैं collection.insert का उपयोग करता हूं तो यह पूरी तरह से काम करता है।
जॉन

क्या यह उस अतिरिक्त सामान के साथ काम करेगा जो मैंगोज़ोज़ स्कीमा प्रदान करता है? अगर कोई तारीख मौजूद नहीं है, तो यह डेटा जोड़ देगाdateCreated : { type: Date, default: Date.now },
जैक रिक्त

22

वास्तव में, आप मानगो के "निर्माण" विधि का उपयोग कर सकते हैं, इसमें दस्तावेजों की एक सरणी हो सकती है, इस उदाहरण को देखें:

Candy.create({ candy: 'jelly bean' }, { candy: 'snickers' }, function (err, jellybean, snickers) {
});

कॉलबैक फ़ंक्शन में सम्मिलित दस्तावेज़ होते हैं। आपको हमेशा पता नहीं होता है कि कितनी वस्तुओं को डाला जाना है (ऊपर दी गई निश्चित तर्क लंबाई) ताकि आप उनके माध्यम से लूप कर सकें:

var insertedDocs = [];
for (var i=1; i<arguments.length; ++i) {
    insertedDocs.push(arguments[i]);
}

अद्यतन: एक बेहतर समाधान

एक बेहतर समाधान के Candy.collection.insert()बजाय उपयोग करना होगा Candy.create()- ऊपर दिए गए उदाहरण में उपयोग किया जाता है - क्योंकि यह तेज़ है ( प्रत्येक आइटम पर create()कॉल Model.save()कर रहा है इसलिए यह धीमा है)।

अधिक जानकारी के लिए मैंगो प्रलेखन देखें: http://docs.mongodb.org/manual/reference/method/db.collection.insert/

( इसे इंगित करने के लिए arcseldon का धन्यवाद )


group.google.com/forum/# ​​.topic / mongoose - orm / IkPmvcd0kds - आप जो चाहते हैं उसके आधार पर, लिंक के पास एक बेहतर विकल्प है।
आर्केल्डन

क्या आपको {type:'jellybean'}इसके बजाय मतलब नहीं है {type:'jelly bean'}? Btw। क्या अजीब प्रकार हैं? क्या वे Mongoose API का हिस्सा हैं?
स्टीव के।

2
वैसे यह एक बुरा नामकरण विकल्प है, क्योंकि typeआम तौर पर एक डेटाबेस ऑब्जेक्ट के ADT को मानने के लिए Mongoose में आरक्षित है।
स्टीव के।

2
@sirbenbenji मैंने इसे बदल दिया, लेकिन यह एक उदाहरण था जो आधिकारिक दस्तावेज में भी मौजूद था। मुझे लगता है कि इसके लिए नीचा दिखाना जरूरी नहीं था।
बेंसके

1
पते पर .collection property द्वारा आप Mongoose (सत्यापन, 'पूर्व' विधियों ...) को दरकिनार कर रहे हैं
Derek

4

आप किसी सरणी में मान सम्मिलित करते हुए mongoDB शेल का उपयोग करके बल्क इंसर्ट कर सकते हैं।

db.collection.insert([{values},{values},{values},{values}]);

वहाँ थोक डालने के लिए एक तरीका है?
सुन्दराजन के

1
YourModel.collection.insert()
बिल दामी

पते पर .collection property द्वारा आप Mongoose (सत्यापन, 'पूर्व' विधियाँ ...) को दरकिनार कर रहे हैं
Derek

यह आम नहीं है, और इस जवाब से कुछ हफ्ते पहले कच्चा collection.insertजवाब दिया गया था, और बहुत अधिक विस्तार से समझाया गया था।
Dan Dascalescu

4

आप उच्चतम स्कोर उत्तर के रूप में मानगो का उपयोग करके थोक सम्मिलित प्रदर्शन कर सकते हैं। लेकिन उदाहरण काम नहीं कर सकता, यह होना चाहिए:

/* a humongous amount of potatos */
var potatoBag = [{name:'potato1'}, {name:'potato2'}];

var Potato = mongoose.model('Potato', PotatoSchema);
Potato.collection.insert(potatoBag, onInsert);

function onInsert(err, docs) {
    if (err) {
        // TODO: handle error
    } else {
        console.info('%d potatoes were successfully stored.', docs.length);
    }
}

बल्क इंसर्ट के लिए स्कीमा इंस्टेंस का उपयोग न करें, आपको एक सादा मानचित्र ऑब्जेक्ट का उपयोग करना चाहिए।


पहला उत्तर गलत नहीं है, यह सिर्फ मान्यता है
लुका स्टीब

1
पते पर .collection property से आप Mongoose (सत्यापन, 'पूर्व' तरीके ...) को दरकिनार कर रहे हैं
डेरेक

4

यहाँ InsertMany और बचत के साथ डेटा को बचाने के दोनों तरीके हैं

1) Mongoose insertManyभारी मात्रा में दस्तावेज़ों को सहेजता है

/* write mongoose schema model and export this */
var Potato = mongoose.model('Potato', PotatoSchema);

/* write this api in routes directory  */
router.post('/addDocuments', function (req, res) {
    const data = [/* array of object which data need to save in db */];

    Potato.insertMany(data)  
    .then((result) => {
            console.log("result ", result);
            res.status(200).json({'success': 'new documents added!', 'data': result});
    })
    .catch(err => {
            console.error("error ", err);
            res.status(400).json({err});
    });
})

2) Mongoose के साथ दस्तावेजों की बचत सरणी .save()

ये दस्तावेज़ समानांतर बचाएंगे।

/* write mongoose schema model and export this */
var Potato = mongoose.model('Potato', PotatoSchema);

/* write this api in routes directory  */
router.post('/addDocuments', function (req, res) {
    const saveData = []
    const data = [/* array of object which data need to save in db */];
    data.map((i) => {
        console.log(i)
        var potato = new Potato(data[i])
        potato.save()
        .then((result) => {
            console.log(result)
            saveData.push(result)
            if (saveData.length === data.length) {
                res.status(200).json({'success': 'new documents added!', 'data': saveData});
            }
        })
        .catch((err) => {
            console.error(err)
            res.status(500).json({err});
        })
    })
})

3

ऐसा लगता है कि मानगो का उपयोग करते समय 1000 से अधिक दस्तावेजों की सीमा होती है

Potato.collection.insert(potatoBag, onInsert);

आप उपयोग कर सकते हैं:

var bulk = Model.collection.initializeOrderedBulkOp();

async.each(users, function (user, callback) {
    bulk.insert(hash);
}, function (err) {
    var bulkStart = Date.now();
    bulk.execute(function(err, res){
        if (err) console.log (" gameResult.js > err " , err);
        console.log (" gameResult.js > BULK TIME  " , Date.now() - bulkStart );
        console.log (" gameResult.js > BULK INSERT " , res.nInserted)
      });
});

लेकिन यह 10000 दस्तावेजों के साथ परीक्षण करते समय लगभग दोगुना है:

function fastInsert(arrOfResults) {
var startTime = Date.now();
    var count = 0;
    var c = Math.round( arrOfResults.length / 990);

    var fakeArr = [];
    fakeArr.length = c;
    var docsSaved = 0

    async.each(fakeArr, function (item, callback) {

            var sliced = arrOfResults.slice(count, count+999);
            sliced.length)
            count = count +999;
            if(sliced.length != 0 ){
                    GameResultModel.collection.insert(sliced, function (err, docs) {
                            docsSaved += docs.ops.length
                            callback();
                    });
            }else {
                    callback()
            }
    }, function (err) {
            console.log (" gameResult.js > BULK INSERT AMOUNT: ", arrOfResults.length, "docsSaved  " , docsSaved, " DIFF TIME:",Date.now() - startTime);
    });
}

1
पते पर .collection property द्वारा आप Mongoose (सत्यापन, 'पूर्व' विधियाँ ...) को दरकिनार कर रहे हैं
Derek

0

हमारी परियोजना से काम करने और संबंधित कोड साझा करना:

//documentsArray is the list of sampleCollection objects
sampleCollection.insertMany(documentsArray)  
    .then((res) => {
        console.log("insert sampleCollection result ", res);
    })
    .catch(err => {
        console.log("bulk insert sampleCollection error ", err);
    });

.insertManyसमाधान पहले से ही दिया गया था (और समझाया गया है) इस में 2016 जवाब
डैन डस्केल्सस्कू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.