0

我正在尝试使用 express 和 node-mysql 将 mysql 数据库中的一些旧数据导出为 JSON。下面的 SQL 工作正常。我正在努力寻找一种简单的方法来加入 getOwnerID 的“结果”以及 compVouchers 中返回的每一行的数据。

我也在使用 async.js 跟随另一个线程,但我不确定这是否有帮助。但是,如果我能侥幸不使用它,那可能会更好。

  //join some tables to get comprehensive voucher data 
    exports.compVouchers = function(req, res) {
        var advertType = '"discount_voucher_all_CANCELLED"';
        if (connection) {
        connection.query('SELECT V.id AS voucher_id, V.title, V.description, V.discount, V.customers_total, V.advert_type, ' +
            'V.customers_redeemed, V.start_date, V.expiry_date, V.redemption_code, ' +
            'K.image, G.latitude, G.longitude FROM '+dbname+'.vouchers AS V ' +
            'LEFT JOIN '+dbname+'.iag_key_tags AS K ON ( V.id = K.id ) ' +
            'LEFT JOIN '+dbname+'.iag_geo_tags AS G ON ( V.id = G.id ) ' +
            'WHERE V.advert_type like '+advertType , function(err, rows, fields) {
                if (err) throw err;
                console.log("Got "+rows.length+" Vouchers:");
               // now get each vouchers owner id
                async.map(rows, getOwnerID, function(err, results){
                res.writeHead(200, {'Content-Type': 'text/plain'});
                res.end(JSON.stringify(results));
                res.end();
                });

            });

        }

    };

        function getOwnerID(voucher, callback) {
            connection.query('SELECT parent_tagid AS owner_id FROM '+dbname+'.iag_key_tag_relationships WHERE TYPE =2 AND tagid =  '+ voucher.voucher_id,  function(err, info) {
                if(err) {
                    console.log(err);
                    return callback(err);
                }
                else {
                    return callback(null, info);
                }
            });
        }

所以

res.end(JSON.stringify(results)); // 仅打印每张凭证的所有 owner_id

res.end(JSON.stringify(rows)); // 打印每张凭证的数据,但不打印 owner_id

将 node-mysql 结果行组合成 node.js的单个 JSON 返回并不能解决问题,但如您所见,我已尝试遵循该线程中的建议。

4

2 回答 2

1

这里比评论更漂亮:) 试试这个:

var result={}, c=rows.length;
function getOwnerID(voucher, cb){
           connection.query('SELECT ...',  function(err, info) {
                if(err) console.log(err);
                else result[info] = voucher;
                if(!--c)return cb();
            });
}

while(rows.length){
 getOwnerID(rows.pop(), function(){
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end(JSON.stringify(results));// {"owner1":{voucher1}, "owner2":{voucher2}}
  res.end();
 })
}
于 2013-08-05T20:07:46.010 回答
0

好的伙计们(感谢@vp_arth 将我推向一个让我接近的有趣方向,错字结果应该是结果顺便说一句)

所以无论如何,我最终得到了一个 hack 解决方案,我正在使用 .push underscore.js 和 .replace 来帮助我清理 JSON 数据,以便以后/下一个可以在像 MongoDB 这样的 nosql 数据库中使用它。

   //declare global array variable... there must be a more elegant solution
    var compV = [];
    exports.compVouchers = function(req, res) {
        var advertType = '"discount_voucher_all_CANCELLED"';
        if (connection) {
        connection.query('SELECT V.id AS voucher_id, V.title, V.description, V.discount, V.customers_total, V.advert_type, ' +
            'V.customers_redeemed, V.start_date, V.expiry_date, V.redemption_code, ' +
            'K.image, G.latitude, G.longitude FROM '+dbname+'.vouchers AS V ' +
            'LEFT JOIN '+dbname+'.iag_key_tags AS K ON ( V.id = K.id ) ' +
            'LEFT JOIN '+dbname+'.iag_geo_tags AS G ON ( V.id = G.id ) ' +
            'WHERE V.advert_type like '+advertType , function(err, rows, fields) {
                if (err) throw err;
                // now get each vouchers owner id
                console.log("Got "+rows.length+" Vouchers:");
                async.each(rows, getOwnerID, function(err, results){
                res.writeHead(200, {'Content-Type': 'text/plain'});
                // now user underscore.js to clean up JSON
                var finalComp = JSON.stringify(un.flatten(un.compact(compV)));
                // finally use replace to customise the known output to merging the voucher and owner into single JSON documents
                var finalComp2 = finalComp.replace(/},{"owner_id/g,',"owner_id'); //not happy with this but it works
                res.write(finalComp2);
                res.end();
                });

            });

        }

    };

        function getOwnerID(voucher, callback) {
            connection.query('SELECT parent_tagid AS owner_id FROM '+dbname+'.iag_key_tag_relationships WHERE TYPE =2 AND tagid =  '+ voucher.voucher_id,  function(err, owner) {
                if(err) {
                    console.log(err);
                    return callback(err);
                }
                else {
                    var arr = [];
                    arr.push(voucher);
                    arr.push(owner);
                    compV.push(arr);  //append to global array variable
                    return callback(null, compV); // doesn't return anything??
                }
            });
        }

也许有一种更优雅的合并方式

[{"F1_field1":"F1_value1","F1_field2":"F1_value2"},{"F2_field1":"F2_value2"}]

进入

[{"F1_field1":"F1_value1","F1_field2":"F1_value2","F2_field1":"F2_value2"}]

这是我带有评论/想法的最终代码

你现在还需要 npm install 下划线添加到 async 并在变量中声明它们......更不用说 node-mysql 和 express......我使用“un”而不是“_”所以我不会混淆稍后可能看起来像 jquery 简写的代码。

于 2013-08-06T09:30:14.737 回答