首页 > 解决方案 > 限制在 express 服务器上运行的异步 BigQuery 作业的数量

问题描述

我有一个从 Google BigQuery 提取数据的快速服务器。提供了一个array对象。我想为 a 中的每个提取销售数据storedistrict但该表仅包含基于store并且没有信息的销售district信息。我通过发送一个查询来完成此操作district,但是一旦数组有超过 50 个区,我就会出错。结果按地区存储在单独的 CSV 文件中。因此,发送单个查询并将其转储到 CSV 中很方便。BigQuery 在给定时间仅允许 50 个作业。我正在寻找将以下代码调整为调用asyncQuery(query)50 次的最佳方法,然后仅在上一个调用返回时才进行下一次调用。我一直在尝试使用 the 来处理工作状态,job.getMetadata()但还没有运气。

谢谢你尽你所能的帮助

const array = [{
        district: "north"
        store: "1001,1002"
    },
    {
        district: "south"
        store: "1003"
    },{
        district: "west"
        store: "1004"
    }
]

function apiCall(array) {
    array.forEach(element => {
        let stores = element.store.toString()
        let query = `SELECT store, sku, tot_sales, price
                      FROM big-query-table 
                      WHERE
                      store IN (${stores})`
        asyncQuery(query)
            .then(resp => {
                console.log(resp)
            }).catch(err => {
                console.error('ERROR:', err);
            })
    })
    return "Running Jobs"
}

function asyncQuery(sqlQuery) {

    const options = {
        query: sqlQuery,
        useLegacySql: false,
    };

    let job;

    return bigquery
        .createQueryJob(options)
        .then(results => {
            job = results[0];
            console.log(`Job ${job.id} started.`);
            return job.promise();
        })
        .then(() => {
            // Get the job's status
            return job.getMetadata();
        })
        .then(metadata => {
            // Check the job's status for errors
            const errors = metadata[0].status.errors;
            if (errors && errors.length > 0) {
                throw errors;
            }
        })
        .then(() => {
            console.log(`Job ${job.id} completed.`);
            return job.getQueryResults();
        })
        .then(results => {
            const rows = results[0];
            return rows;
        })
        .catch(err => {
            console.error('ERROR:', err);
        });
}

标签: node.jsgoogle-bigquery

解决方案


使用 BigQuery - 以及任何其他柱状分析数据库 - 您确实希望避免执行 50 个查询,例如:

[*50] SELECT * FROM big-query-table WHERE storeNumber = ${StoreNumber}

相反,您可以做的最好的事情是一个查询,指定您正在寻找的列,以及您正在寻找的所有 id:

SELECT col1, col2, col3
FROM big-query-table 
WHERE storeNumber IN ('id1', 'id2', ..., 'id50')

或者直接加入:

SELECT col1, col2, col3
FROM big-query-table 
WHERE storeNumber IN (SELECT store_id FROM `table`)

这样您就不需要发送 50 个并发查询,而且您会以更少的时间和更低的成本获得结果。


推荐阅读