alguien me puede ayudar para saber cómo se puede ejecutar mangosta consulta en bucle forEach en nodejs y sugieren para inner join resultado de la necesidad de ambas colecciones

como se muestra a continuación detalla

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 Comentarios

  1. 1

    Usted puede utilizar esta:

    db.collection.find(query).forEach(function(err, doc) {
      //...
    });
    • He ganancia de un error es: .forEach no es una función. Por qué?
    • porque foreach es un nativo de mongodb función no es una función de la mangosta
  2. 11

    Esquema.find() es un async función. Así que en su última línea de código se ejecutará mientras se espera para el primer trabajo de búsqueda se ejecuta en el bucle. Sugiero cambiar a las Promesas y el uso de la Promesa.todos(matriz).

    Para ello, primero tiene que cambiar el uso de la Promesa con la mangosta. usted puede hacer esto con bluebird como este:

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

    A continuación, puede utilizar las Promesas en lugar de las devoluciones de llamada como esta:

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

    EDITAR Cómo la lista de trabajos, y los usuarios

    Si quieres tener una estructura como:

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

    usted podría combinar las listas. listOfJobs en el mismo orden como el jobQueries lista, por lo que están en el mismo orden que el de los usuarios. Ahorrar a los usuarios a un ámbito compartido para acceder a la lista de la ‘función’ y, a continuación, combinar.

    ..
    }).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);
    });
    • gracias por la ayuda, pero tengo una pregunta que cómo puede imprimir la lista de puestos de trabajo y los usuarios
    • mostrar este error—->Aplicación se Inició en el PUERTO 8080 express obsoleto res.enviar(estado, cuerpo): Uso de la res.status(estado).enviar(cuerpo) en lugar de en App/Controllers/Api/MarketController.js:36:23 (nodo:15265) UnhandledPromiseRejectionWarning: no Controlada promesa de rechazo (rechazo de identificación: 1): RangeError: no Válido código de estado: 0 (nodo:15265) DeprecationWarning: no Controlada promesa rechazos están en desuso. En el futuro, la promesa de rechazos que no son manejados terminará el Node.js con un proceso de salida distinto de cero código.
    • usted todavía necesita la captura.. me deja actualizar mi respuesta de ‘…’ para la captura
    • Me gustaría añadir que sólo funcionó para mí una vez que he añadido una devolución de llamada a la línea de jobQueries.push(jobSchema.find({u_sno:s.u.sno})); así que se convirtió en jobQueries.push(jobSchema.find({u_sno:s.u.sno}), () => {});
    • Intente agregar la mangosta.Promesa = global.La promesa de donde se conecta a la mangosta. Bluebird es un es5 Promesa lib. pero con las versiones posteriores de nodo, usted tiene la Promesa en el mundial
  3. 2

    No hay necesidad de utilizar forEach() que es sincrónico y siendo llamado asíncrono, de la moda, que le dará malos resultados.

    Puede utilizar el marco de agregación y utilizar $de búsqueda que realiza una combinación externa izquierda para otra colección en la misma base de datos para filtrar en los documentos de la «unió» de la colección para su procesamiento.

    Para la misma consulta se puede hacer uso de una sola agregación de tuberías como:

    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
            })
        );
    })
    • sugieren que necesito inner join nos gusta, tenemos tanto en el resultado de los usuarios y jos algo que uno a uno de la tabla de
    • ¿Cuál es tu servidor de MongoDB versión?
    • su versión 3.2
    • mongodb no soporta la combinación interna, sino que sólo admite combinación externa izquierda.
  4. 0

    Una buena solución elegante es utilizar el cursor.eachAsync() función. Crédito a https://thecodebarbarian.com/getting-started-with-async-iterators-in-node-js.

    La eachAsync() función ejecuta un (potencialmente async), función
    cada uno de los documentos que el cursor se devuelve. Que si la función devuelve un
    promesa, espere a que se comprometan a resolver antes de llegar a la
    el siguiente documento. Esta es la manera más fácil de escape de un cursor en
    mangosta.

      //A cursor has a `.next()` function that returns a promise. The promise
      //will resolve to the next doc if there is one, or null if they are no
      //more results.
      const cursor = MyModel.find().sort({name: 1 }).cursor();
    
      let count = 0;
      console.log(new Date());
      await cursor.eachAsync(async function(doc) {
        //Wait 1 second before printing first doc, and 0.5 before printing 2nd
        await new Promise(resolve => setTimeout(() => resolve(), 1000 - 500 * (count++)));
        console.log(new Date(), doc);
      });

Dejar respuesta

Please enter your comment!
Please enter your name here