2016-10-06 11 views
1

私はnodejsとLoopback/Expressを初めて使用しています。私は関連するモデルの複数のdb要求を持つAPI呼び出しを含む簡単なアプリケーションを作成しようとしていますが、これを示す関連ドキュメントや例は見つかりません。リモートメソッドの関連モデルの複数のクエリ

著者、投稿、評価の3つのモデルを想像してみてください。各投稿にhasOne AuthorとhasMany Ratingsがあります。 Ratingsには「星」と呼ばれる整数値があります。 (関連Authorモデルに格納されている)

  • 投稿詳細
  • 著者の詳細
  • 私は、次のすべてを返す必要があります「詳細」と呼ばれる記事のカスタムAPIのremoteMethodを作成しています関連する評価の関連評価持つ星の関連評価持つ星の数は== 1

  • 数は== 2
  • 数持つ星== 3

これを実装する最善の方法は、最も少ない並列クエリ数を持つクエリですか?私は約束を使用して次のコードを試しましたが、本質的にそれはデータベースへの複数の不要なクエリを作成する非効率的な同期コードであり、すぐに非常に乱雑になります。

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'を使用しようとしましたが、使用するのが難しくなり、ループバックでレベル2フィルタをサポートしません。

これを実装するにはどうすればよいですか?

少しリファクタリングと変更とまあ
+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はクエリを並列に実行し、指定されたすべてのクエリが完了すると終了します。
関連する問題