Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在循环多个db.Phrase.find调用时使用回调正确地从mongodb传递数据_Javascript_Mongodb - Fatal编程技术网

Javascript 如何在循环多个db.Phrase.find调用时使用回调正确地从mongodb传递数据

Javascript 如何在循环多个db.Phrase.find调用时使用回调正确地从mongodb传递数据,javascript,mongodb,Javascript,Mongodb,我正在从get请求接收参数,如下所示: { location: 'Venice', weather: 'Dry', what: 'Yoga', who: 'Bob' } 然后我查询一个mongodb数据库,该数据库循环遍历每个键和值对,并在数据库中查询它们的联合 然后,我将返回的值保存到outputCaption,然后使用回调将outputCaption传回 问题是回调调用的次数与它们的键值对循环的次数相同 我被迫这样做,因为我需要db.Phrase.find调用中的回调,但我多次调用它 因此

我正在从get请求接收参数,如下所示:

{ location: 'Venice', weather: 'Dry', what: 'Yoga', who: 'Bob' }
然后我查询一个mongodb数据库,该数据库循环遍历每个键和值对,并在数据库中查询它们的联合

然后,我将返回的值保存到outputCaption,然后使用回调将outputCaption传回

问题是回调调用的次数与它们的键值对循环的次数相同

我被迫这样做,因为我需要db.Phrase.find调用中的回调,但我多次调用它

因此,我使用app.get中的代码修复了它(我等待所有键在outputCaption中定义了值,然后才执行任何操作)

这是可行的,但我无法想象这是最好的方法,所以我希望有一个不那么刻薄的方法? 谢谢

server.js

var express = require('express');
var db = require('./modules/db')
var logic = require('./modules/logic')

...

app.get('/phrase', function(req, res){
  logic(req.query, function(outputCaption){
    var flag = true
    for (key in outputCaption){
      if (outputCaption[key] === null){
        console.log('Incomplete')
        var flag = false;
      }
    }
    if (flag === true) {
      console.log(outputCaption);
    };
  });
})

...
logic.js

var db = require('./db')

var logic = function(params, callback){
  var outputCaption = {
    who: null, 
    what: null, 
    location: null, 
    weather: null
  };
  for (key in params){
    category = key.toLowerCase();
    option = params[key].toLowerCase();
    db.Phrase.find({$and: [
      {category: category}, 
      {option: option}
      ]}, function(err, phrases){
        if (err) return console.error(err);
        var options = Object.keys(phrases).length
        var idxOfOptionPicked = Math.floor(Math.random() * options)
        outputCaption[phrases[idxOfOptionPicked].category] = phrases[idxOfOptionPicked].phrase
        callback(outputCaption)
    })
  }
}

module.exports = logic;

使用查询操作符允许
MongoDB
为您进行联合,而不是在客户端触发多个查询并执行结果的联合

这样你:

  • 避免多次点击数据库
  • 避免使用多个回调处理程序
  • 可以在单个回调处理程序中对结果进行后期处理
您可以修改代码,以根据请求参数准备查询对象

  var params = {location: 'Venice', weather: 'Dry', what: 'Yoga', who: 'Bob' };
  var query = {};
  var conditions = [];
  Object.keys(params).forEach(function(key){
   var $and = {};
   $and["category"] = key.toLowerCase();
   $and["option"] = params[key];
   conditions.push($and);
  });
  (conditions.length > 1)?(query["$or"] = conditions):(query = conditions[0]);
现在,构造的查询如下所示:

{ '$or': 
   [ { category: 'location', option: 'Venice' },
     { category: 'weather', option: 'Dry' },
     { category: 'what', option: 'Yoga' },
     { category: 'who', option: 'Bob' } 
   ] 
}
您可以将此对象传递给
find()
方法,以在一次点击中获得结果:

db.Phrase.find(query,callback);

这样,您的代码将更清晰、更容易理解。

尝试提交帮助请求!非常好-谢谢-这正是我想要的