MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

MongoDB-Mongoose-Filialdokumente wurden zweimal erstellt

Die forEach-Schleife in Ihrem Versuch erkennt die Callback-Vervollständigung von findById() nicht async-Methode vor der nächsten Iteration. Sie müssen einen von async verwenden Bibliotheksmethoden async.each , async.while , oder async.until die einer for-Schleife entsprechen und warten, bis der Callback von async aufgerufen wird, bevor sie mit der nächsten Iteration fortfahren (mit anderen Worten, einer for-Schleife, die nachgibt).

Zum Beispiel:

var platform_docs = [];
async.each(platforms, function(id, callback) {
    Platform.findById(id, function(err, platform) {
        if (platform) 
            platform_docs.push(platform);
        callback(err);
    });
}, function(err) {
   // code to run on completion or err
   console.log(platform_docs);
});

Für den gesamten Vorgang könnten Sie den Code async.waterfall() Methode, die es jeder Funktion ermöglicht, ihre Ergebnisse an die nächste Funktion weiterzugeben.

Die erste Funktion in der Methode erstellt den neuen Artikel.

Die zweite Funktion verwendet async.each() Hilfsfunktion zum Durchlaufen der Plattformliste, Ausführen einer asynchronen Aufgabe für jede ID zum Aktualisieren der Plattform mit findByIdAndUpdate() , und wenn sie alle fertig sind, geben Sie die Ergebnisse der Aktualisierungsabfrage in einer Objektvariablen an die nächste Funktion zurück.

Die letzte Funktion aktualisiert den neu erstellten Artikel mit den Plattform-IDs aus der vorherigen Pipeline.

Etwas wie das folgende Beispiel:

var newArticle = {},
    platforms            = req.body.platforms,
    date                 = req.body.date,
    split                = date.split("/");

newArticle.title         = req.body.title;
newArticle.description   = req.body.description;
newArticle.date          = split[2]+'/'+split[0]+'/'+split[2];
newArticle.link          = req.body.link;
newArticle.body          = req.body.body;
console.log(platforms);

async.waterfall([

    // Create the article
    function(callback) {
        var article = new Article(newArticle);
        article.save(function(err, article){
            if (err) return callback(err);                  
            callback(null, article);
        });
    },

    // Query and update the platforms 
    function(articleData, callback) {
        var platform_ids = [];
        async.each(platforms, function(id, callback) {
            Platform.findByIdAndUpdate(id, 
                { "$push": { "articles": articleData._id } },
                { "new": true },
                function(err, platform) {
                    if (platform) 
                        platform_ids.push(platform._id);
                    callback(err);
                }
            );
        }, function(err) {
            // code to run on completion or err
            if (err) return callback(err);                  
            console.log(platform_ids);
            callback(null, {
                "article": articleData,
                "platform_ids": platform_ids
            });
        });         
    },

    // Update the article
    function(obj, callback) {
        var article = obj.article;
        obj.platform_ids.forEach(function(id){ article.platforms.push(id); });
        article.save(function(err, article){
            if (err) return callback(err);                  
            callback(null, article);
        });
    }   

], function(err, result) { 
/*
    This function gets called after the above tasks 
    have called their "task callbacks"
*/
    if (err) return next(err);
    console.log(result);
    res.redirect('articles/' + result._id);
});