0

Express と node-mysql を使用して、mysql db からレガシー データを 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(結果)); // 各バウチャーのみのすべての owner_id を出力します

res.end(JSON.stringify(行)); // 各バウチャーのデータを出力しますが、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

OK みんな (@vp_arth さん、興味深い方向に私を近づけてくれてありがとう、タイプミスの結果は結果になるはずです)

.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 underscore を async に追加し、それらを変数で宣言する必要があります... node-mysql と express は言うまでもありません...「_」の代わりに「un」を使用したので、混乱しません後で jquery の略記のように見えるかもしれないコード。

于 2013-08-06T09:30:14.737 に答える