2 回答

TA貢獻(xiàn)1155條經(jīng)驗(yàn) 獲得超0個(gè)贊
BigQuery 旨在與為不同編程語言編寫的各種不同客戶端庫一起使用,因此,它不返回特定于 nodejs 的數(shù)據(jù)結(jié)構(gòu),而是返回大多數(shù)結(jié)構(gòu)化編程語言通用的更通用的結(jié)構(gòu),例如作為對象?;卮鹉膯栴},是的,有一種方法可以將 BigQuery 數(shù)據(jù)流式傳輸?shù)角岸?,但這是一個(gè)相當(dāng)個(gè)人的選擇,因?yàn)樗枰闹皇菑囊环N數(shù)據(jù)類型轉(zhuǎn)換為另一種數(shù)據(jù)類型。但是,我想說最直接的方法是調(diào)用JSON.stringify()
,您已經(jīng)提到過。

TA貢獻(xiàn)1826條經(jīng)驗(yàn) 獲得超6個(gè)贊
我們最終制作了一個(gè)實(shí)現(xiàn),將 BigQuery 的回復(fù)拼接到一個(gè)大的 JSON 數(shù)組中:
exports.stream = (query, params, res) => {
// Light testing for descriptive errors in the parameters
for (let key in params) {
if (typeof params[key] === "number" && isNaN(params[key])) {
throw new TypeError(`The parameter "${key}" should be a number`);
}
}
return new Promise((resolve, reject) => {
let prev = false;
const onData = row => {
try {
// Only handle it when there's a row
if (!row) return;
// There was a previous row written before, so add a comma
if (prev) {
res.write(",");
}
res.write(stringify(row));
prev = true;
} catch (error) {
console.error("Cannot parse row:", error);
// Just ignore it, don't write this frame
}
};
const onEnd = () => {
res.write("]");
res.end();
resolve();
};
res.writeHead(200, { "Content-Type": "application/json" });
res.write("[");
bigQuery
.createQueryStream({ query, params })
.on("error", reject)
.on("data", onData)
.on("end", onEnd);
});
};
它將通過拼接來構(gòu)建一個(gè)大型 JSON 數(shù)組:
[ // <- First character sent
stringify(row1) // <- First row
, // <- add comma on second row iteration
stringify(row2) // <- Second row
...
stringify(rowN) // <- Last row
] // <- Send the "]" character to close the array
這有以下優(yōu)點(diǎn):
數(shù)據(jù)在可用時(shí)立即發(fā)送,因此帶寬需求較低。
(取決于 BigQuery 實(shí)現(xiàn))服務(wù)器端的內(nèi)存需求較低,因?yàn)椴⒎撬袛?shù)據(jù)都一次保存在內(nèi)存中,只有小塊。