当前位置: 首页 > 面试题库 >

使用#standardSQL在BigQuery上运行异步JS函数

澹台俊达
2023-03-14
问题内容

现在,BigQuery在#standardSQL上支持异步了,如何将这个#legacySQL函数转换为在#standardSQL上运行?

#legacySQL
SELECT SUM(s)
FROM
js((
  SELECT FLOOR(RAND()*100000) group, NEST(requests) as x
  FROM (
    SELECT requests, content_size
    FROM [fh-bigquery:wikipedia.pagecounts_201205]
  )
  GROUP BY group)
  , group, x
  , "[{name:'s', type: 'float'}]",
"function (row, emit) {
  const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 });
  const env = {
      'abortStackOverflow': _ => { throw new Error('overflow'); },
      'table': new WebAssembly.Table({ initial: 0, maximum: 0, element: 'anyfunc' }),
      'tableBase': 0,
      'memory': memory,
      'memoryBase': 1024,
      'STACKTOP': 0,
      'STACK_MAX': memory.buffer.byteLength,
  };
  const imports = { env };
  const bytes = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 139, 128, 128, 128, 0, 2, 96, 1, 127, 0, 96, 2, 127, 127, 1, 127, 2, 254, 128, 128, 128, 0, 7, 3, 101, 110, 118, 8, 83, 84, 65, 67, 75, 84, 79, 80, 3, 127, 0, 3, 101, 110, 118, 9, 83, 84, 65, 67, 75, 95, 77, 65, 88, 3, 127, 0, 3, 101, 110, 118, 18, 97, 98, 111, 114, 116, 83, 116, 97, 99, 107, 79, 118, 101, 114, 102, 108, 111, 119, 0, 0, 3, 101, 110, 118, 6, 109, 101, 109, 111, 114, 121, 2, 1, 128, 2, 128, 2, 3, 101, 110, 118, 5, 116, 97, 98, 108, 101, 1, 112, 1, 0, 0, 3, 101, 110, 118, 10, 109, 101, 109, 111, 114, 121, 66, 97, 115, 101, 3, 127, 0, 3, 101, 110, 118, 9, 116, 97, 98, 108, 101, 66, 97, 115, 101, 3, 127, 0, 3, 130, 128, 128, 128, 0, 1, 1, 6, 147, 128, 128, 128, 0, 3, 127, 1, 35, 0, 11, 127, 1, 35, 1, 11, 125, 1, 67, 0, 0, 0, 0, 11, 7, 136, 128, 128, 128, 0, 1, 4, 95, 115, 117, 109, 0, 1, 9, 129, 128, 128, 128, 0, 0, 10, 196, 128, 128, 128, 0, 1, 190, 128, 128, 128, 0, 1, 7, 127, 2, 64, 35, 4, 33, 8, 35, 4, 65, 16, 106, 36, 4, 35, 4, 35, 5, 78, 4, 64, 65, 16, 16, 0, 11, 32, 0, 33, 2, 32, 1, 33, 3, 32, 2, 33, 4, 32, 3, 33, 5, 32, 4, 32, 5, 106, 33, 6, 32, 8, 36, 4, 32, 6, 15, 0, 11, 0, 11]);
WebAssembly.instantiate(bytes, imports).then(wa => {
      const exports = wa.instance.exports;
      const sum = exports._sum;
      for (var i = 0, len = row.x.length; i < len; i++) {
        emit({s: sum(row.x[i], row.x[i])});
      }
  });
}"
)

(来自https://medium.com/@hoffa/bigquery-beyond-sql-and-js-running-c-and-rust-
code-at-scale-33021763ee1f


问题答案:

现在,您可以创建一个async function x(),然后返回x()

而不是能够emit()多次,您必须将结果嵌套到数组中。

工作示例:

CREATE TEMP FUNCTION `magic_function`(x ARRAY<INT64>) RETURNS ARRAY<INT64> LANGUAGE js AS '''
const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 });

const env = {
    'abortStackOverflow': _ => { throw new Error('overflow'); },
    'table': new WebAssembly.Table({ initial: 0, maximum: 0, element: 'anyfunc' }),
    'tableBase': 0,
    'memory': memory,
    'memoryBase': 1024,
    'STACKTOP': 0,
    'STACK_MAX': memory.buffer.byteLength,
};

const imports = { env };

const bytes = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 139, 128, 128, 128, 0, 2, 96, 1, 127, 0, 96, 2, 127, 127, 1, 127, 2, 254, 128, 128, 128, 0, 7, 3, 101, 110, 118, 8, 83, 84, 65, 67, 75, 84, 79, 80, 3, 127, 0, 3, 101, 110, 118, 9, 83, 84, 65, 67, 75, 95, 77, 65, 88, 3, 127, 0, 3, 101, 110, 118, 18, 97, 98, 111, 114, 116, 83, 116, 97, 99, 107, 79, 118, 101, 114, 102, 108, 111, 119, 0, 0, 3, 101, 110, 118, 6, 109, 101, 109, 111, 114, 121, 2, 1, 128, 2, 128, 2, 3, 101, 110, 118, 5, 116, 97, 98, 108, 101, 1, 112, 1, 0, 0, 3, 101, 110, 118, 10, 109, 101, 109, 111, 114, 121, 66, 97, 115, 101, 3, 127, 0, 3, 101, 110, 118, 9, 116, 97, 98, 108, 101, 66, 97, 115, 101, 3, 127, 0, 3, 130, 128, 128, 128, 0, 1, 1, 6, 147, 128, 128, 128, 0, 3, 127, 1, 35, 0, 11, 127, 1, 35, 1, 11, 125, 1, 67, 0, 0, 0, 0, 11, 7, 136, 128, 128, 128, 0, 1, 4, 95, 115, 117, 109, 0, 1, 9, 129, 128, 128, 128, 0, 0, 10, 196, 128, 128, 128, 0, 1, 190, 128, 128, 128, 0, 1, 7, 127, 2, 64, 35, 4, 33, 8, 35, 4, 65, 16, 106, 36, 4, 35, 4, 35, 5, 78, 4, 64, 65, 16, 16, 0, 11, 32, 0, 33, 2, 32, 1, 33, 3, 32, 2, 33, 4, 32, 3, 33, 5, 32, 4, 32, 5, 106, 33, 6, 32, 8, 36, 4, 32, 6, 15, 0, 11, 0, 11]);

async function main() {
  const wa = await WebAssembly.instantiate(bytes, imports);
  const exports = wa.instance.exports;
  const magic_sum = exports._sum;
  return x.map((val) => {
    return magic_sum(val, val);
  });
}

return main();

''';

SELECT SUM(s) sum_s
FROM (
  SELECT FLOOR(RAND()*100000) grp, magic_function(ARRAY_AGG(views)) s
  FROM `fh-bigquery.wikipedia_v3.pageviews_2019` 
  WHERE DATE(datehour) = '2019-01-01' AND wiki='pt'
  GROUP BY grp
), UNNEST(s) s

(https://issuetracker.google.com/issues/138430827#comment9)(h
/ t https://twitter.com/mylesborins)



 类似资料:
  • 通过使用 Web Worker 在单独的线程中运行一个函数,允许长时间运行的函数不会阻塞 UI。 使用 Blob 对象URL创建一个新的Worker,其内容应该是所提供函数的字符串化版本。 立即发送回调用函数的返回值。 返回一个 promise ,监听 onmessage 和 onerror 事件并解析 worker 发回的数据,或者抛出一个错误。 const runAsync = fn => {

  • 问题内容: 我试图将两个异步函数链接在一起,因为第一个具有条件返回参数,导致第二个运行或退出模块。但是,我发现规格中找不到奇怪的行为。 这是我的代码的混帐摘要(您可以在此处查看完整的范围),该代码只是检查玩家是否已经在大厅中,但这无关紧要。 接下来,我们有这个异步功能。 如果,则无需运行此功能。 我试着做 我希望这将等待结果,以便可以有条件地运行,但是我收到了没有具体细节的类型错误。 为什么您不能

  • 如何在组件返回中使用promise函数,如下所示: 因此,结果将是: 即使我在同一个组件中有几个promise,我也必须使用?

  • 问题内容: 总的来说,我对Swift和Xcode还是比较陌生,并且发现很多困难要设法解决。 我正在开发一个利用后端服务器的应用程序。为了不阻塞主线程,每当应用程序从服务器下载任何内容时,它都会异步地在其他线程上完成。但是,其余代码将继续在主线程上执行,并且当应该从服务器下载的数据尚未下载时,它将崩溃。我想知道如何在异步函数完成后调用函数来运行,这对于单独文件中的函数必须完成。 我读过闭包可能对此有

  • 问题内容: 我想要实现的是Web钩子应该等待,直到我从api调用获得响应为止。PS:API正在起作用,只是机器人不等待响应到来。任何帮助将不胜感激。谢谢 问题答案: 您没有说明要在什么环境中运行,但是鉴于您的代码以及上面概述的更改,我可以使用Firebase Cloud Functions和node.js 6.14复制您的问题。 我可以通过使用包而不是来使它正常工作。顾名思义,它使用本机Promi

  • 我有一个异步函数,它在代码中的某个地方按setInterval运行。此函数定期更新一些缓存。 我还有一个不同的同步函数,它需要检索值——最好是从缓存中检索,但如果是缓存未命中,则从数据源检索(我意识到以同步方式进行IO操作是不明智的,但假设在这种情况下需要这样做)。 我的问题是,我希望同步函数能够等待异步函数中的值,但是不可能在非异步函数中使用关键字: 现在,通过将中的逻辑提取到一个新的同步函数中