2017-04-15 138 views
0

我在數據庫中使用mLab和節點js.mig中使用mongoose。我正在使用不應該引起任何問題的swagger。我有以下模式。當用戶請求時,如果(查看=真)在查詢中,我需要一起返回電影和查看。一部電影可能有多個評論。首先,我必須在數據庫中找到所有電影。當我找到電影時,我必須仔細閱讀其中的每一個,在另一個數據庫中查找任何評論,並以某種方式將它們附加到電影中。我需要將所有電影歸還到一個包中,因爲它將用於getAll函數。無論我做什麼,只會在沒有評論的情況下回覆電影。 組合兩個表/集合的mongodb/mongoose聚合

var mongoose = require('mongoose'); 
 

 
var reviewSchema = new mongoose.Schema({ 
 
    movie:  {type: String, required: true}, 
 
    reviewer: {type: String, required: true}, 
 
    rating:  {type: Number, required:true, min: 1, max: 5}, 
 
    text:  {type: String, required: true}, 
 
}) 
 

 

 
var movieSchema = new mongoose.Schema({ 
 
    Title:   {type: String, required: true, unique: true}, 
 
    YearReleased: {type: Number, required: true}, 
 
    Actors:   [{ 
 
         Name: {type: String, required: true} 
 
    }] 
 
})

 movies.forEach(function(movie, index){ 
      // this call is asynchronous, res.send will run before the callback 
      db.Reviews.find({movie:movies[index].Title}, function (err, review) { 
       if(err) throw {err:err} 
       movies[index].Review = review // I am trying to populate each movie with reviews 
      }); 
     }); 
     res.send({Movielist: movies}); 

您可以使用承諾等待結果:前DB審查結果被接收

function getAll(req,res,next){ 
 
    db.Movies.find({},function(err,movies){ 
 
     if(err) throw {err:err}; 
 
     if(req.swagger.params.review.value === false) 
 
      res.send({Movielist: movie}); 
 
     else { 
 
      movies.forEach(function(movie, index){ 
 
       db.Reviews.find({movie:movies[index].Title}, function (err, review) { 
 
        if(err) throw {err:err} 
 
        movies[index].Review = review // I am trying to populate each movie with reviews 
 
       }); 
 
      }); 
 
      res.send({Movielist: movies}); 
 
     } 
 

 
    }); 
 
}

回答

0

res.send被調用。我將舉一個異步/等待的例子。使用不帶異步/等待的承諾也是一種選擇。

async function getAll(req,res,next) { 
    try { 
    let movies = await getMovies(); 
    res.send(movies); 
    } catch (err) { 
    console.log(err.stack); 
    } 
} 

async function getMovies() { 
    return new Promise(function (resolve, reject) { 
    db.Movies.find({},function(err,movies){ 
     if(err) reject(err); 
     if(req.swagger.params.review.value === false) 
      resolve({Movielist: movie}); 
     else { 
     movies.forEach(function(movie, index){ 
      let review = await getReviews(); 
      movies[index].Review = review 
     }); 
     resolve({Movielist: movies}); 
     } 
    }); 
    }); 
} 

async function getReviews (movie, index) { 
    return new Promise(function (resolve, reject) { 
    db.Reviews.find({movie:movies[index].Title}, function (err, review) { 
     if(err) reject({err:err}); 
     resolve(review); 
    }); 
    }); 
} 

這可能需要一些調整,因爲我沒有測試過它。我希望它給出瞭如何解決這個問題的總體思路。

沒有異步/等待您可以調用承諾並運行「.then」來處理結果。如果你還沒有使用諾言,那麼一些谷歌搜索應該有助於理解如何工作。

0

首先謝謝@curtwphillips 但是,我找到了簡短的方法來做到這一點。但爲了這個工作,電影和評論必須在同一個數據庫作爲不同的收藏。如果使用不同的數據庫,這是行不通的

function getAll(req,res,next) { 
 
    if (req.query.review === 'true') { 
 
     db.Movies.aggregate([ 
 
      { 
 
       $lookup: { 
 
        from: "reviews", 
 
        localField: "Title", 
 
        foreignField: "movie", 
 
        as: "review" 
 
       } 
 
      } 
 
     ], function (err, result) { 
 
      if (err) throw {err: err}; 
 
      else { 
 
       res.send({Movielist: result}); 
 
      } 
 
     }); 
 
    } 
 
    else { 
 
     db.Movies.find({}, function (err, movies) { 
 
      if (err) throw {err: err}; 
 
      res.send({Movielist: movies}) 
 
     }) 
 
    } 
 
}