MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

MongoDB sottodocumenti mongoose creati due volte

Il ciclo forEach nel tuo tentativo non riconosce il completamento della callback di findById() metodo asincrono prima dell'iterazione successiva. Devi utilizzare uno qualsiasi dei async metodi della libreria async.each , async.whilst o async.until che sono equivalenti a un ciclo for e attenderanno finché non viene richiamata la richiamata di async prima di passare all'iterazione successiva (in altre parole, un ciclo for che produrrà).

Ad esempio:

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

Per l'intera operazione, puoi utilizzare async.waterfall() metodo che consente a ciascuna funzione di passare i propri risultati alla funzione successiva.

La prima funzione nel metodo crea il nuovo articolo.

La seconda funzione usa async.each() funzione di utilità per scorrere l'elenco delle piattaforme, eseguire un'attività asincrona per ciascun ID per aggiornare la piattaforma utilizzando findByIdAndUpdate() , e al termine restituiscono i risultati della query di aggiornamento in una variabile oggetto alla funzione successiva.

La funzione finale aggiornerà l'articolo appena creato con gli ID piattaforma della pipeline precedente.

Qualcosa come il seguente esempio:

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