Mongoose - 如何将结果保存到数组中

时间:2018-04-06 14:38:58

标签: javascript arrays mongodb mongoose

我有一个mongodb查询,我想将结果保存到数组中。我还在查询之外定义了一个空数组。

       var dietaryResults = [];

       for (var key in dietary){
            Restaurant.find(
                { $text : { $search : dietary[key] } },
                { score : { $meta: "textScore" } }
            ).sort({ score : { $meta : 'textScore' } }).exec(function(err, results) {
                for (var i in results){
                    dietaryResults.push(results[i]);
                }
                console.log(dietaryResults);
            });
        }

如果我在上面的查询中console.log(dietaryResults),我可以看到结果被推入数组。但是如果我把console.log(dietaryResults)放在数组之外(这就是我想要的),它会打印一个空字符串。任何人都可以解释这种行为,并建议一个解决方案吗?感谢。

4 个答案:

答案 0 :(得分:1)

Restaurant.find是异步的。

函数insinde .exec部分在循环结束后执行。

尝试

 for (var key in dietary){
        Restaurant.find(
            { $text : { $search : dietary[key] } },
            { score : { $meta: "textScore" } }
        ).sort({ score : { $meta : 'textScore' } }).exec(function(err, results) {
            for (var i in results){
                dietaryResults.push(results[i]);
            }
            console.log('added');
        });
    }
 console.log('loop end');

你将能够看到,那个循环结束'在添加'之前将打印日志。登录。 如果你需要数组中的所有结果,你应该在回调中填充这个数组。没有办法同步获取数据。

有关回调和异步函数的详细信息,请查看以下文章:https://www.tutorialspoint.com/nodejs/nodejs_callbacks_concept.htm

我建议一次搜索所有必需的数据,并避免在内部循环中搜索单个回调,并在回调中执行所需的一切结果。

像这样的Smth可能会起作用。如果不是,您应该搜索某种方式来获取一个请求中的所有数据

 Restaurant.find(
    { $text : { $search : { $in: Object.values(dietary)} } },
    { score : { $meta: "textScore" } }
 ).sort({ score : { $meta : 'textScore' } }).exec(function(err, results) {
    for (var i in results){
        dietaryResults.push(results[i]);
    }
        //do stuff here;
    });

答案 1 :(得分:1)

当我使用bluebird(这是一种Promise)时,它可以正常工作。

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

 var promises = Restaurant.find({ $text : { $search : query } }, function(err, results) {
     results.forEach(function(element) {
         finalResults.push(element);
     });
 });

 Promise.all(promises).then(function() {
     console.log(finalResults);
 }).error(console.error);

答案 2 :(得分:0)

你需要回调或承诺。你可以在这个**餐厅之外使用。(** 这样:setTimeOut(function s(){console.log(dietaryResults)},1000)

因为您需要学习异步功能。

答案 3 :(得分:0)

javascript asynchronicity方式开始,您无法确定{for循环结束前.exec回调是否会运行(并结束)。 (通过阅读event-loop

,您可以更好地理解这个主题

这样,dietaryResults在任何其他地方都可以为空(取决于查询速度)。

You can read more about using promises with mongoose and node in order to be sure dietaryResults will be full with the results, 阅读Node event loop

,也可以更好地理解这一主题

目前,我不完全确定这会奏效 - 但这是你的方向:

var query = {...} // (enter your query here) 
var dietaryResults = [];

Object.entries(diatery).map(async key => {
  const results = await Restaurant.find(query).sort();
  results.map(result => dietaryResults.push(result));
});

console.log(dietaryResults);