如何在forEach循环中运行mongoose查询

时间:2017-01-19 14:13:56

标签: node.js mongodb express mongoose

任何人都可以帮助我如何在nodejs中的forEach循环中运行mongoose查询并建议两个集合的内部联接结果需要

如下所示

x1 = np.arange(4)
x2 = np.arange(4,8)
x3 = np.arange(8,12)
x.append(x1)
x.append(x2)
x.append(x3)
x = np.array(x)

print x.shape
(3, 4)

4 个答案:

答案 0 :(得分:11)

Schema.find()是一个异步函数。因此,当您等待在循环中执行第一个作业搜索时,您的最后一行代码将会执行。我建议将其更改为Promises并使用Promise.all(array)。

要这样做,首先必须更改为使用带有猫鼬的Promise。你可以用蓝鸟这样做:

raise('abort')

然后你可以使用Promises而不是像这样的回调:

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

编辑如何列出作业和用户

如果您想拥有如下结构:

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

您可以将列表合并在一起。 listOfJobs与jobQueries列表的顺序相同,因此它们与用户的顺序相同。将用户保存到共享范围以访问“then函数”中的列表,然后合并。

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

答案 1 :(得分:2)

无需使用同步并以异步方式调用的 forEach() ,这会给您错误的结果。

您可以使用聚合框架并使用 $lookup 执行左外连接到同一数据库中的另一个集合,以过滤来自“已加入”集合的文档以进行处理。 / p>

因此,使用单个聚合管道可以完成相同的查询:

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 :(得分:1)

您可以使用:

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

答案 3 :(得分:0)

一个不错的优雅解决方案是使用cursor.eachAsync()函数。归功于https://thecodebarbarian.com/getting-started-with-async-iterators-in-node-js

  

eacherAsync()函数执行一个(可能异步)的函数   光标返回的每个文档。如果该函数返回一个   承诺,它将等待该承诺解决后再获得   下一个文件。这是在其中耗尽光标的最简单方法   猫鼬。

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