web-dev-qa-db-fra.com

comment peut exécuter la requête mangouste dans la boucle forEach

quelqu'un peut-il m'aider pour savoir comment exécuter une requête mangouste dans une boucle forEach dans nodejs et suggérer un résultat de jointure interne 

comme ci-dessous détails

userSchema.find({}, function(err, users) {
    if (err) throw err;
    users.forEach(function(u,i){
        var users = [];
        jobSchema.find({u_sno:s.u.sno}, function(err, j) {
            if (err) throw err;
            if (!u) {
                res.end(JSON.stringify({
                    status: 'failed:Auction not found.',
                    error_code: '404'
                }));
                console.log("User not found.");
                return 
            }
            users.Push(j);
        })
    })
    res.send(JSON.stringify({status:"success",message:"successfully done",data:{jobs:j,users:u}}));
})
4
lakshman

Vous pouvez utiliser ceci:

db.collection.find(query).forEach(function(err, doc) {
  // ...
});
0
tdog

Schema.find () est une fonction asynchrone. Ainsi, votre dernière ligne de code sera exécutée pendant que vous attendez que la première recherche d’emploi soit exécutée dans votre boucle. Je suggère de le changer à Promises et d'utiliser Promise.all (tableau).

Pour ce faire, vous devez d’abord changer d’utilisation de Promise avec mangouste. vous pouvez le faire avec bluebird comme ceci:

var mongoose = require('mongoose');
mongoose.Promise = require('bluebird');

Ensuite, vous pouvez utiliser Promises au lieu de rappels comme ceci:

userSchema.find({}).then(function(users) {
  var jobQueries = [];

  users.forEach(function(u) {
    jobQueries.Push(jobSchema.find({u_sno:s.u.sno}));
  });

  return Promise.all(jobQueries );
}).then(function(listOfJobs) {
    res.send(listOfJobs);
}).catch(function(error) {
    res.status(500).send('one of the queries failed', error);
});

EDITComment lister les tâches et les utilisateurs

Si vous voulez avoir une structure comme:

[{ 
  user: { /* user object */,
  jobs: [ /* jobs */ ]
}]

vous pouvez fusionner les listes ensemble. listOfJobs est dans le même ordre que la liste de jobQueries, donc dans le même ordre que les utilisateurs. Enregistrez les utilisateurs dans une étendue partagée pour accéder à la liste dans la fonction 'then' puis fusionner.

..
}).then(function(listOfJobs) {
  var results = [];

  for (var i = 0; i < listOfJobs.length; i++) {
    results.Push({
      user: users[i],
      jobs: listOfJobs[i]
    });
  }

  res.send(results);
}).catch(function(error) {
  res.status(500).send('one of the queries failed', error);
});
10
R. Gulbrandsen

Pas besoin d'utiliser forEach() qui soit synchrone et appelé de manière asynchrone, cela vous donnera des résultats erronés.

Vous pouvez utiliser la structure d'agrégation et utiliser $lookup pour effectuer une jointure externe gauche sur une autre collection de la même base de données afin de filtrer les documents de la collection "jointe" aux fins de traitement.

Donc, la même requête peut être faite en utilisant un seul pipeline d'agrégation tel que:

userSchema.aggregate([
    {
        "$lookup": {
            "from": "jobs", /* underlying collection for jobSchema */
            "localField": "sno",
            "foreignField": "u_sno",
            "as": "jobs"
        }
    }
]).exec(function(err, docs){
    if (err) throw err;
    res.send(
        JSON.stringify({
            status: "success",
            message: "successfully done",
            data: docs
        })
    );
})
2
chridam