简体   繁体   English

猫鼬-如何将结果保存到数组

[英]Mongoose - How to save results to an array

I have a mongodb query and I want to save the results to an array. 我有一个mongodb查询,我想将结果保存到数组中。 I also define an empty array outside of query. 我还在查询之外定义了一个空数组。

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

If I do console.log(dietaryResults) inside the query like above, I can see the results being pushed into the array. 如果我在上面的查询中执行console.log(dietaryResults) ,我可以看到结果被推送到数组中。 But if I put console.log(dietaryResults) outside of the array (which what I want), it prints an empty string. 但是,如果我将console.log(dietaryResults)放在数组之外(我想要的),它将打印一个空字符串。 Can anyone explain this behavior and suggest a solution for this? 谁能解释这种行为并提出解决方案? Thanks. 谢谢。

Restaurant.find is asynchronous. Restaurant.find是异步的。

Function insinde .exec part is being executed after loop ends. 循环结束后,将执行函数insinde .exec部分。

Try 尝试

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

You will be able to see, that 'loop end' log will be printed before 'added' log. 您将看到,“循环结束”日志将在“添加”日志之前打印。 If you need all results in array, you should fill this array in callback. 如果需要数组中的所有结果,则应在回调中填充此数组。 There is no way to get data synchronously. 无法同步获取数据。

For more information about callbacks and async functions check out this article: https://www.tutorialspoint.com/nodejs/nodejs_callbacks_concept.htm 有关回调和异步函数的更多信息,请查看本文: https : //www.tutorialspoint.com/nodejs/nodejs_callbacks_concept.htm

I'd suggest to search for all required data at once and avoid searching inside loop to have single callback and do everything you need with results inside that callback. 我建议一次搜索所有必需的数据,避免在循环内搜索单个回调,并在该回调内执行结果所需的一切。

Smth like this may work. 这样的事情可能会起作用。 If not you should search for some way to get all data in one request 如果不是,您应该寻找某种方法来在一个请求中获取所有数据

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

When I use bluebird (which is a kind of Promise ) it works. 当我使用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);

You need callback or promise.You can use outside of this **Restaurant.find( ** this: setTimeOut(function s(){console.log(dietaryResults)},1000) 您需要回调或Promise。您可以在** Restaurant.find(** this: setTimeOut(function s(){console.log(dietaryResults)},1000)

Because you need to learn async functions. 因为您需要学习异步功能。

As of javascript asynchronicity fashion, You can't be sure that the .exec callback will run (and end) before the for loop end. javascript异步.exec来看,您无法确定.exec回调将在for循环结束之前运行(并结束)。 (you can have a better understanding on this topic by reading about the event-loop ) (通过阅读有关事件循环,您可以对此主题有更好的理解)

This way, dietaryResults can be empty (depend on the query speed) in any other place. 这样, dietaryResults在其他任何地方都可以为空(取决于查询速度)。

You can read more about using promises with mongoose and node in order to be sure dietaryResults will be full with the results , and also have better understanding on this topic by reading about Node event loop . 您可以阅读有关将承诺与猫鼬和节点一起使用的更多信息,以确保dietaryResults包含完整的结果 ,并且通过阅读有关Node事件循环的信息 ,可以更好地理解该主题。

For now, I'm not fully sure this will work - but that's is your direction: 目前,我还不确定这是否行得通-但这就是您的方向:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM