在 REST API 中合并 2 个查询的输出

Combine output of 2 queries in REST API

我正在使用 node.js restify 模块。我有一个 REST API,它在 json 中输出单个 MySQL 查询的结果。这是 API;

的代码
var rest_api_get_list = function (app, url_name) {
    function respond(req, res, next) {
        var door_mac = req.query.door_mac;

        var connection = own_mysql.getMySQL_connection();

        var query_str =
                "SELECT doors.mac_addr, " +
                "sensors.sensor_type " +
                "FROM sensors " +
                "WHERE (doors.mac_addr = ?) "
            ;

        var query_var = [door_mac];

        var query = connection.query(query_str, query_var, function (err, rows, fields) {
            //if (err) throw err;
            if (err) {
                //throw err;
                console.log(err);
                logger.info(err);
            }
            else {
                res.send(rows);
            }
        }); 
        return next();
    }

    app.get(url_name, respond);
};

假设我有另一个类似这样的查询;

    var query_str_2 =
            "SELECT knobs.mac_addr, " +
            "furniture.furniture_type " +
            "FROM furnitures" +
            "WHERE (knobs.mac_addr = ?) "
        ;

我想合并 2 个 MySQL 查询 query_strquery_str_2 的输出,并将 REST API return 结果放入 json。如何才能做到这一点?

为了更清楚,我正在考虑代码做这样的事情;

var rest_api_get_list = function (app, url_name) {
    function respond(req, res, next) {
        var door_mac = req.query.door_mac;

        var connection = own_mysql.getMySQL_connection();

        var query_str =
                "SELECT doors.mac_addr, " +
                "sensors.sensor_type " +
                "FROM sensors " +
                "WHERE (doors.mac_addr = ?) "
            ;

        var query_var = [door_mac];

        var query = connection.query(query_str, query_var, function (err, rows_output_1, fields) {
            //if (err) throw err;
        }); 

        var query_str_2 =
            "SELECT knobs.mac_addr, " +
            "furniture.furniture_type " +
            "FROM furnitures" +
            "WHERE (knobs.mac_addr = ?) "
        ;

        var query_2 = connection.query(query_str_2, query_var, function (err, rows_output_2, fields) {
            //if (err) throw err;

        }); 

        //How to display json output of rows_output_1 and rows_output_2?

        return next();
    }

    app.get(url_name, respond);
};

编辑:我开始悬赏以吸引使用 Promises 的答案。

用于管理异步控制流的模块 - 如 async - 可以帮助您。

例如:

function respond(req, res, next) {

    var door_mac = req.query.door_mac;
    var connection = own_mysql.getMySQL_connection();
    var query_var = [door_mac];

    async.parallel([
        function (callback) {

            var query_str =
                "SELECT doors.mac_addr, " +
                "sensors.sensor_type " +
                "FROM sensors " +
                "WHERE (doors.mac_addr = ?) "
            ;
            connection.query(query_str, query_var, callback); 
        },
        function (callback) {

            var query_str_2 =
                "SELECT knobs.mac_addr, " +
                "furniture.furniture_type " +
                "FROM furnitures" +
                "WHERE (knobs.mac_addr = ?) "
            ;
            connection.query(query_str_2, query_var, callback);
        }
    ], function (error, results) {

        // results[0] => result for query_str
        // results[1] => result for query_str_2
        // ... return next() or whatever
    })       
}

如果您要求并行性,如@cartant 所说,您可以使用 async 或(更好的)promises (Promise.all(p1, p2).then(...)).

但是如果您要求最佳方法(并行性以每次实际结果消耗更多资源为代价提供更快的结果),您可以改为在单个查询中完成:

var query_str =
    "SELECT doors.mac_addr, " +
    "sensors.sensor_type as type " +
    "FROM sensors " +
    "WHERE (doors.mac_addr = ?) " +
    "UNION " +
    "SELECT knobs.mac_addr, " +
    "furniture.furniture_type as type " +
    "FROM furnitures" +
    "WHERE (knobs.mac_addr = ?) "
;

这样你执行单个数据库调用,当然,数据库不会执行任何并行性,而是会尽最大努力在最佳时间以较低的资源消耗获得答案。

因此,如果您必须处理更多请求,平均效率甚至会更好,另一方面,如果您在资源不太关心的环境中请求更快的结果,那么并行方法会更好。