Orm 如何在sailsjs控制器中运行多个查询?

Orm 如何在sailsjs控制器中运行多个查询?,orm,sails.js,Orm,Sails.js,在sailsjs中,一次只能运行和传递一组查询数据。例如,这里是我的主页的控制器: module.exports = { index: function (req, res) { Blog.find() .limit(3) .sort('createdAt desc') .where({ isPublished: 1 }) .exec(function(err, posts) {

在sailsjs中,一次只能运行和传递一组查询数据。例如,这里是我的主页的控制器:

     module.exports = {

       index: function (req, res) {

        Blog.find()
        .limit(3)
        .sort('createdAt desc')
        .where({ isPublished: 1 })
        .exec(function(err, posts) {
          if (err) return next(err);
          res.view({
            layout: "homeLayout",
            posts:posts
          });    
        });  
      }

    };

我如何从其他模型中查询数据,并将其与我已经传递的博客数据一起传递给我的视图?

我已经想出了一些方法来实现这一点。第一种方法是嵌套查询,例如

Blog.find()
  .limit(30)
  .sort('createdAt desc')
  .where({ isPublished: 1 })
  .exec(function(err, posts) {

        SomeOtherModel.find()
        .limit(5)
        .sort('createdAt desc')
        .where({ isPublished: 1 })
        .exec(function(err, otherdata) {

          res.view({
            posts: posts,
            otherdata: otherdata
          });

      });

}); 
第二种方法是使用承诺(我以前不知道这一点)

第三种方法(我最后使用了这种方法)是创建一个策略(特定于sailsjs,但它是express中间件)


这样做您不需要向视图传递任何内容,但是我不确定向响应对象随机添加数据是否是一种好的做法。

您可以使用承诺来实现这一点。这实际上是一个很好的用例。 我使用,这是(赛欧的ORM)在幕后使用的

您可以在下面看到一个代码示例,其中我从第一个模型检索数据,然后使用检索到的数据查询其他模型以获取更多数据(并行),最后将结果发送回视图

SomeModel.findOne(标准)。然后(函数(结果){
所有人([
SomeOtherModel.getSomething(结果),
YetAnotherModel.getSomethingElse(结果)
]).spread(函数(someOtherResult,yetAnotherResult){
风险值数据={
事情:结果,
材料:其他结果,
其他事物:yetAnotherResult
};
返回res.view(数据);
});
}).失败(功能(原因){
返回res.view(原因);
});
getSomething()
函数应该返回一个承诺,来自Sails的标准查找器将透明地工作(只是不要通过回调)。标准查找器的行为似乎与Q承诺不完全一样,我在这里给出的答案应该有助于获得更一致的行为


您也可以使用async.auto(见下文)。下面是一个完整的sails回购示例

var async = require('async'),
    _ = require('lodash');

module.exports = {


    index: function (req, res) {

        async.auto({

            // Get the blog posts
            posts: function (cb) {
                Blog.find()
                    .where({ isPublished: 1 })
                    .limit(5)
                    .sort('createdAt DESC')
                    .exec(cb);
            },


            // Get some more stuff
            // (this will happen AT THE SAME TIME as `posts` above)
            otherThings: function (cb) {
                OtherThing.find()
                    .limit(30)
                    .exec(cb);
            },


            // Get comments
            // (we'll wait until `posts` is finished first)
            comments: ['posts', function (cb, async_data) {

                // Get `posts`
                // (the second argument to cb() back in `posts`)
                // Used map to make sure posts are an array of ids and not just an object. 
                var posts = async_data.posts.map(function (item){ return item.id});

                // Get comments that whose `post_id` is equal to 
                // the id of one of the posts we found earlier
                Comment.find()
                    .where({ post_id: posts })
                    .exec(cb);
            }]

        },
        function allDone (err, async_data) {

            // If an error is passed as the first argument to cb
            // in any of the functions above, then the async block
            // will break, and this function will be called.
            if (err) return res.serverError(err);

            var posts = async_data.posts;
            var comments = async_data.comments;

            var otherThings = async_data.otherThings;

            // Fold the comments into the appropriate post
            // An in-memory join
            _.map(posts, function (post) {
                var theseComments =
                    _.where(comments, { post_id: post.id });
                post.comments = theseComments;

            });

            // Show a view using our data
            res.json({
                // layout: 'homeLayout',
                posts: posts,
                otherThings: otherThings
            });
        });

    }
};

因此,以下是如何发出3个请求并将其所有数据传递到视图中:

第一次安装Q

npm install q
然后使用下面的代码,用您的模型替换我的模型:

// first import Q
var Q = require('q');

// Let's combine results of 3 queries
Q.all([
      // let's find one user with name "Pavel"
      User.findOne({name: 'Pavel'}).then(),

      // let's find one Lexus car
      Cars.findOne({brand: 'Lexus'}).then(),

      // Finally let's get the first Apple phone
      Phones.findOne({brand: 'Apple'}).then()
    ])
.spread(function (user, car, phone) {
  // Output results as json, but you can do whatever you want here
  res.json([user, car, phone]);
}).fail(function (reason) {
  // output reason of failure
  res.json(reason);
});

有相当多的讨论正在进行,以摆脱Q库,而不是使此可插拔,如ES6承诺、蓝鸟等。请参阅:@Arceldon是的,我是关于Waterline的一个老讨论的一部分:但它从未被合并。Sails的团队对性能和承诺总体上感觉不太好。@Arceldon事实上,他们刚刚合并了另一个pull请求:是的,在我关注github回购协议时看到了这一点。聊天结束后准时:)如果请求是独立的,Bluebird是很棒的或异步并行的
npm install q
// first import Q
var Q = require('q');

// Let's combine results of 3 queries
Q.all([
      // let's find one user with name "Pavel"
      User.findOne({name: 'Pavel'}).then(),

      // let's find one Lexus car
      Cars.findOne({brand: 'Lexus'}).then(),

      // Finally let's get the first Apple phone
      Phones.findOne({brand: 'Apple'}).then()
    ])
.spread(function (user, car, phone) {
  // Output results as json, but you can do whatever you want here
  res.json([user, car, phone]);
}).fail(function (reason) {
  // output reason of failure
  res.json(reason);
});