it-swarm.com.de

Mongoose (Mongodb) Batch einfügen?

Unterstützt Mongoose v3.6 + jetzt Stapeleinsätze? Ich habe ein paar Minuten gesucht, aber alles, was mit dieser Abfrage übereinstimmt, ist ein paar Jahre alt und die Antwort war ein eindeutiges Nein.

Bearbeiten:

Zum späteren Nachschlagen lautet die Antwort Model.create(). create() akzeptiert ein Array als erstes Argument, sodass Sie Ihre Dokumente übergeben können, um sie als Array einzufügen.

Siehe Model.create () - Dokumentation

106
Geuis

Model.create () vs Model.collection.insert (): ein schnellerer Ansatz

Model.create() ist eine schlechte Methode, um Einfügungen vorzunehmen, wenn Sie mit einer sehr großen Masse arbeiten. Es wird sehr langsam sein . In diesem Fall sollten Sie Model.collection.insert Verwenden, was eine viel bessere Leistung erbringt . Abhängig von der Größe der Masse stürzt Model.create() sogar ab! Versuchte mit einer Million Dokumente, kein Glück. Mit Model.collection.insert Dauerte es nur ein paar Sekunden.

Model.collection.insert(docs, options, callback)
  • docs ist das einzufügende Array von Dokumenten;
  • options ist ein optionales Konfigurationsobjekt - siehe the docs
  • callback(err, docs) wird aufgerufen, nachdem alle Dokumente gespeichert wurden oder ein Fehler aufgetreten ist. Bei Erfolg ist docs das Array der beständigen Dokumente.

Wie der Autor von Mongoose hervorhebt hier , umgeht diese Methode alle Validierungsverfahren und greift direkt auf den Mongo-Treiber zu. Dies ist ein Kompromiss, den Sie eingehen müssen, da Sie eine große Datenmenge verarbeiten. Andernfalls könnten Sie diese Daten überhaupt nicht in Ihre Datenbank einfügen (denken Sie daran, dass wir hier über Hunderttausende von Dokumenten sprechen).

Ein einfaches Beispiel

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);
    }
}

Update 2019-06-22 : Obwohl insert() weiterhin verwendet werden kann, wurde es zugunsten von abgelehnt. insertMany() . Die Parameter sind exakt gleich, Sie können sie also einfach als Ersatz verwenden und alles sollte gut funktionieren (der Rückgabewert ist ein bisschen anders, aber Sie verwenden ihn wahrscheinlich trotzdem nicht).

Referenz

150
Lucio Paiva

Mongoose 4.4.0 unterstützt jetzt Bulk Insert

Mongoose 4.4.0 führt --true-- bulk insert mit der Modellmethode .insertMany() ein. Es ist viel schneller, als .create() zu durchlaufen oder es mit einem Array zu versehen.

Verwendung:

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

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

Oder

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

Sie können es auf verfolgen:

108
Derek

In der Tat können Sie die "create" -Methode von Mongoose verwenden, sie kann eine Reihe von Dokumenten enthalten, siehe folgendes Beispiel:

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

Die Rückruffunktion enthält die eingefügten Dokumente. Sie wissen nicht immer, wie viele Elemente eingefügt werden müssen (feste Argumentlänge wie oben), damit Sie sie durchlaufen können:

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

Update: Eine bessere Lösung

Eine bessere Lösung wäre die Verwendung von Candy.collection.insert() anstelle von Candy.create() - im obigen Beispiel verwendet -, da dies schneller ist (create() ruft Model.save() auf) jedes Element ist also langsamer).

Weitere Informationen finden Sie in der Mongo-Dokumentation: http://docs.mongodb.org/manual/reference/method/db.collection.insert/

(Danke an arcseldon für den Hinweis)

23
benske

Sie können die Masseneinfügung mithilfe der mongoDB-Shell ausführen, indem Sie die Werte in ein Array einfügen.

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

Sie können die Masseneinfügung mit Mungo als Antwort mit der höchsten Punktzahl durchführen. Aber das Beispiel kann nicht funktionieren, es sollte sein:

/* 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);
    }
}

Verwenden Sie keine Schema-Instanz für die Masseneinfügung. Sie sollten ein einfaches Kartenobjekt verwenden.

4
user2582680

Hier haben Sie beide Möglichkeiten, Daten mit insertMany zu speichern und zu speichern

1) Mongoose speichert eine Reihe von Dokumenten mit insertMany in loser Schüttung

/* 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 speichere eine Reihe von Dokumenten mit .save()

Diese Dokumente werden parallel gespeichert.

/* 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
Arpit

Es scheint, dass es bei der Verwendung von Mungo ein Limit von mehr als 1000 Dokumenten gibt

Potato.collection.insert(potatoBag, onInsert);

Sie können verwenden:

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)
      });
});

Dies ist jedoch fast doppelt so schnell beim Testen mit 10000 Dokumenten:

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);
    });
}
3
ddennis

Ich habe async-forEach ( Link für async-forEach npm-Paketdokumentation ) verwendet, um dasselbe zu erreichen.

Mein Code-Snippet ist wie folgt. Ich erhalte die Dokumente im angeforderten Ordner.

var forEach = require('async-foreach').forEach;    
exports.save_Ctrl = function (req, res) {    
//  var l=req.body;
//  console.log("length:",l.length);

 forEach(req.body, function(item, index, object,err) {

    console.log(req.body[index]);
    var post = new saveObj(req.body[index]);   

        //save model to MongoDB
    post.save(function (err) {
        if (err) {
            console.log('error saving :' + err.message);
            return err;
        }   
        else {
            console.log("Post saved");
        }
    });       

  });    
 }

Arbeits- und relevanten Code aus unserem Projekt teilen:

//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);
    });
1
student