2016-10-06 101 views
1

我是nodejs和Loopback/Express的新手。我試圖編寫一個涉及API調用的簡單應用程序,它有多個相關模型的db請求,但我沒有找到任何相關的文檔或示例來說明這一點。遠程方法中的相關模型的多個查詢

想象一下3個模型:作者,發佈和評級。每篇文章有一個作者,並擁有許多評級。評級有一個稱爲'星星'的整數值。

我創建的帖子被稱爲「細節」,這應該返回以下所有的自定義API remoteMethod:

  • 帖子詳細介紹
  • 作者的詳細信息(存儲在相關作者機型)
  • 具有分相關評分數目== 1
  • 具有分相關評分數目== 2
  • 相關評分數目具有分== 3

什麼是最好的方式來實現這個最低和更平行的數據庫查詢?我已經使用Promises嘗試了以下代碼,但本質上這是一個效率低下的同步代碼,它會對數據庫進行多次不必要的查詢,並且它很快變得非常混亂。

Post.details = function(id, cb) { 

var LoopBackContext = require('loopback-context'); 
var app = require('../../server/server'); 
var Author = app.models.Author; 
var Rating = app.models.Rating; 

var response = {post: null, 
       author: null, 
       ratings_0: null, 
       ratings_1: null, 
       ratings_2: null 
    }; 

Post.findById(id, {include: 'author', where: {deleted: false}}) 
    .then(function(p) { 
     response.post = p; 
     return Author.findById(p.authorId); 
    }) 
    .then(function(r) { 
     response.author = r; 
     return Rating.find({where: {postId: id, stars: 0}}); 
    }) 
    .then(function(r) { 
     response.votes_0 = r.length; 
     return Rating.find({where: {postId: id, stars: 1}}); 
    }) 
    .then(function(r) { 
     response.votes_1 = r.length; 
     return Rating.find({where: {postId: id, stars: 2}}); 
    }) 
    .then(function(r) { 
     response.votes_2 = r.length; 
     cb(null, response); 
    }); 

    }; 

這對於這樣一件小事來說太過分了。我也嘗試在查詢中使用'include',但它也變得很難使用,並且它不支持Loopback中的二級過濾器。

實現此目的的最佳方式是什麼?

+0

您可以與Promise.all同時處理所有這些請求 –

回答

1

那麼一點點的重構和改變,這將是非常簡短易懂:

Post.details = function(id) { 
    var app = require('../../server/server'); 
    var Rating = app.models.Rating; 

    return Promise.all([ 
    Post.findById(id, {include: 'author', where: {deleted: false}}), 
    Rating.count({ where: {postId: id, stars: 0}}), 
    Rating.count({ where: {postId: id, stars: 1}}), 
    Rating.count({ where: {postId: id, stars: 2}}), 
    ]).then([post, ratings_0, ratings_1, ratings_2]) => { 
    return { 
     post, 
     author: post.author, 
     ratings_0, 
     ratings_1, 
     ratings_2, 
    }; 
    }); 
}; 

有幾件事情怎麼回事:

  • 你不需要Author.findById,假設include: 'author'涵蓋它。
  • 至於收視率方面,您剛剛使用了Rating.count方法。由於使用的帶寬較少,並且數據庫可以更快地提供數據,所以它會更快,因爲它將直接從索引提供。
  • 我已經使用ES6破壞,對象字面速記和箭頭功能。
  • 如果您在回送遠程方法中返回承諾,它將使用請求響應的方法返回值而不是回調。
  • Promise.all將並行運行查詢,並在所有給定查詢完成時結束。