远程方法中的相关模型的多个查询
我是nodejs和Loopback / Express的新手。 我试图写一个简单的应用程序,涉及一个API调用,有相关模型的多个数据库请求,但我没有find任何相关的文档或例子,显示这一点。
想象3种模式:作者,发布和评级。 每个职位都有一个作者,并拥有许多评级。 评级具有一个称为“星星”的整数值。
我正在创build一个名为'details'的post的自定义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中的二级filter。
什么是实施这个最好的方法?
那么稍微重构一下,就会变得非常简短:
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
方法。 由于使用的带宽较less,并且数据库可以更快地提供数据,所以它会更快,因为它将直接从索引提供。 - 我用ES6破坏,对象文字速记和箭头function。
- 如果您在回送远程方法中返回承诺,它将使用请求响应的方法返回值而不是callback。
- Promise.all将并行运行查询,并在所有查询完成时结束。