2016-08-08 13 views
8

Tôi đang sử dụng mô-đun khôi phục node.js. Tôi có một API REST để xuất kết quả của một truy vấn MySQL đơn lẻ trong json. Đây là mã của API;Kết hợp đầu ra của 2 truy vấn trong REST 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); 
}; 

Giả sử tôi có một truy vấn trông giống như thế này;

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

Tôi muốn kết hợp đầu ra của 2 MySQL truy vấn query_strquery_str_2 và có REST API trả về kết quả trong json. Điều này có thể giải quyết như thế nào?

Để rõ ràng hơn, tôi đang nghĩ đến mã làm một việc như thế này;

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); 
}; 

EDIT: Tôi bắt đầu một tiền thưởng để thu hút câu trả lời sử dụng Lời hứa.

+1

Bạn đang hỏi cách thực hiện hai truy vấn hoặc bạn có thực sự đặt câu hỏi SQL về cách tham gia không? – HeadCode

+0

HeadCode, Xin lỗi vì không rõ ràng. Đây không phải là một câu hỏi SQL. Tôi hỏi làm thế nào để làm 2 truy vấn và trả về kết quả kết hợp của 2 truy vấn trong json. Tôi đã chỉnh sửa câu hỏi để làm cho nó rõ ràng hơn. Cảm ơn bạn. –

+1

Phần khó khăn cho vấn đề này là bản chất không đồng bộ của node.js. Các truy vấn không thể chạy cái này sau cái kia. Nó sẽ rất thú vị để xem cách Promises hoặc các mô-đun như bluebird được sử dụng để trả lời câu hỏi này. – user781486

Trả lời

6

Mô-đun để quản lý luồng điều khiển không đồng bộ - như async - có thể giúp bạn với điều này.

Ví dụ:

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 
    })  
} 
+0

Cảm ơn. Được thăng hạng. Tôi sẽ thử nó. Bạn sẽ biết làm thế nào giải pháp có thể sử dụng Promises hoặc một cái gì đó như module bluebird? –

+1

Mã trong câu hỏi của bạn liên quan đến API dựa trên gọi lại, vì vậy câu trả lời của tôi đã tính đến điều đó. Có, bạn có thể sử dụng lời hứa, nhưng bạn cần phải sử dụng một cái gì đó như [promisify] (http://bluebirdjs.com/docs/api/promise.promisify.html) của bluebird để chuyển đổi API dựa trên gọi lại thành lời hứa- API dựa. Khi bạn có API trả về lời hứa, bạn sẽ thực hiện [Promise.all] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all) để 'kết hợp' kết quả. – cartant

+0

Cảm ơn. Tôi đoán giải pháp của bạn bằng cách sử dụng gọi lại và async sẽ là gọn gàng nhất kể từ mã gốc liên quan đến API dựa trên cuộc gọi lại. –

3

Nếu bạn đang yêu cầu xử lý song song, như @cartant nói, bạn có thể sử dụng async hoặc (tốt hơn nhiều) lời hứa (Promise.all(p1, p2).then(...)).

Nhưng nếu bạn đang yêu cầu cách tiếp cận tối ưu (xử lý song song cho kết quả nhanh hơn với chi phí của nhiều nguồn lực hơn cho mỗi tiêu thụ kết quả thực tế), bạn có thể làm điều đó trong một truy vấn duy nhất thay vì:

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 = ?) " 
; 

Bằng cách này bạn thực hiện duy nhất cơ sở dữ liệu gọi và, tất nhiên, cơ sở dữ liệu sẽ không thực hiện bất kỳ song song, nhưng thay vào đó, nó sẽ làm cho nỗ lực tốt nhất của mình để có được câu trả lời tại thời điểm tốt nhất với mức tiêu thụ tài nguyên thấp hơn. Vì vậy, nếu bạn phải tham dự nhiều yêu cầu hơn, hiệu quả trung bình sẽ tốt hơn, mặt khác, nếu bạn yêu cầu kết quả nhanh hơn trong một môi trường mà tài nguyên không quan tâm nhiều, thì cách tiếp cận song song sẽ tốt hơn.

+1

Việc hợp nhất kết quả cũng rất tốn kém. Nó có thể là với số lượng lớn dữ liệu sẽ nhanh hơn để thực hiện một truy vấn đơn lẻ, sau đó hai truy vấn song song. – Eyal

+0

Đúng vậy. Ít nhất là cho một _union_ đơn giản.Các mẫu hợp nhất phức tạp hơn có thể dễ dàng hơn để tối ưu hóa song song. Đặc biệt khi không phải tất cả các truy vấn (của phiên bản riêng) đều rất lớn. Nhưng, nói chung, sự thật của nó: xử lý các chuyển đổi dữ liệu lớn trong bộ nhớ giống như đau trong ass ;-) – bitifet

Các vấn đề liên quan