【问题标题】:BigQuery UDF reducing all rowsBigQuery UDF 减少所有行
【发布时间】:2016-02-11 06:59:30
【问题描述】:

我定义了以下 UDF(注意我的表有一个“Id”和一个带有子字段“RawHex”的“Reading”对象):

// UDF definition
function hexdecode(row, emit) {
  emit({
    Id: row.Id,
    converted: decodeHelper(row.Reading.Raw)
  });
}

// Helper function with error handling
function decodeHelper(s) {
  try {
    return parseInt(s, 16);
  } catch (ex) {
    return s;
  }
}

// UDF registration
bigquery.defineFunction(
  'hexdecode',  // Name used to call the function from SQL

  ['Id', 'Reading.Raw'],  // Input column names

  // JSON representation of the output schema
  [{name: 'Id', type: 'STRING'},
   {name: 'converted', type: 'INTEGER'}],

  hexdecode  // The function reference
);

我的查询是:

select Id, converted from 
hexdecode(
select r.Id, r.Reading.Raw from Example.TagRaw2 r
)

通过将以下 JSON 上传到表 Example.TagRaw2 生成

{"Id":"ABC","Reading":{"Raw":"0004"}}
{"Id":"CDE","Reading":{"Raw":"000b"}}

我希望这会将我的列从十六进制转换为整数,但如果返回一个几乎没有意义的条目。

知道我做错了什么吗?

编辑:我添加了一个示例 JSON 来上传以尝试重现问题.. 但它现在似乎可以工作了。如果我能找出最初的错误,我会再次更新,但上面的 UDF 似乎完全符合我的要求。

【问题讨论】:

  • 为什么要发出“TagId”,而将架构名称定义为“Id”?
  • 您介意在/输出中包含样本吗?
  • 有点难,因为我不确定我可以公开发布什么 - 我会尝试使用合成集重新创建问题。
  • 请在你这样做的时候ping一下!
  • @FelipeHoffa 我添加了一个 JSON,您可以上传以获取我的表格布局...不幸的是,现在查询工作正常...

标签: google-bigquery udf


【解决方案1】:

问题 - 您的 Reading 对象是否是重复列?

如果是这样,您需要执行以下操作:

function hexdecode(r, emit) {
  for (var i = 0; i < r.reading.length; ++i) {
    emit({ tag: r.Id, num: parseInt(r.reading[i].Raw, 16) });
  }
}

bigquery.defineFunction(
  'hexdecode',
  ['Id', 'reading.Raw'],
  [{name: 'tag', type: 'string'},
   {name: 'num', type: 'integer'}],
  hexdecode
);

如果您尝试访问 r.reading.Raw,这将尝试访问 JavaScript 数组的 Raw 属性。这是完全有效的 JavaScript,但它肯定不是你想要的,因为它的值是未定义的 (null)。

一个方便的技巧是打印出输入记录的 JSON 字符串,以查看 UDF 将什么视为输入:

bigquery.defineFunction(
  'jsonifyObj',
  ['Id', 'reading.Raw'],
  [{name: 'obj', type: 'string'}],
  function(r, emit) { emit({obj: JSON.stringify(r)}); }
);

这有助于调试问题。我怀疑这种情况下的问题是您的数据看起来更像

[{"Id":"ABC","Reading":[{"Raw":"0004"}, {"Raw": "00ff"}]},
 {"Id":"CDE","Reading":[{"Raw":"000b"}, {"Raw": "0012"}]}]

-------- 2015-11-17 更新 --------

您的代码有一些问题,注释如下:

function hexdecode(row, emit) {
 for (var i = 0; i < row.reading.length; ++i) {
   // NOTE: tag and row.Id are wrong, this must be TagId and row.TagId based on your input and output specifications
   emit({ tag: row.Id,
          times: row.reading[i].Timestamp,
          // NOTE: You're making a recursive call here!  You should be calling decodeHelper() not hexdecode().
          convert: hexdecode(row.reading[i].RawCO) });
  }
}


// Helper function with error handling
function decodeHelper(s) {
  try {
    return parseInt(s, 16);
  } catch (ex) {
    return s;
  }
}

// UDF registration
bigquery.defineFunction(
  'hexdecode',  // Name used to call the function from SQL

  ['TagId', 'reading.Timestamp', 'reading.RawCO'],  // Input column names

  // JSON representation of the output schema
  [{name: 'TagId', type: 'STRING'},
   {name: 'times', type: 'INTEGER'},
   {name: 'convert', type: 'INTEGER'}],

  hexdecode  // The function reference
);

您的嵌套选择返回 0 行,所以我更新为以下 SQL:

select 
  TagID, times, convert 
from  hexdecode(
select r.TagId, r.Reading.Timestamp, r.Reading.RawCO from [table.Readings] r where r.Reading.RawCO is not NULL and r.Reading.PPM is
 not NULL
 and r.TagId = 'Tag_00000000' 
 )

这里是更正后的代码:

function hexdecode(row, emit) {
  for (var i = 0; i < row.reading.length; ++i) {
    emit({TagId: row.TagId, times: row.reading[i].Timestamp, convert: decodeHelper(row.reading[i].RawCO)});
  }
}

// Helper function with error handling
function decodeHelper(s) {
  try {
    return parseInt(s, 16);
  } catch (ex) {
    return s;
  }
}

// UDF registration
bigquery.defineFunction(
  'hexdecode',  // Name used to call the function from SQL

  ['TagId', 'reading.Timestamp', 'reading.RawCO'],  // Input column names

  // JSON representation of the output schema
  [{name: 'TagId', type: 'STRING'},
   {name: 'times', type: 'INTEGER'},
   {name: 'convert', type: 'INTEGER'}],

  hexdecode  // The function reference
);

【讨论】:

  • 太棒了..我想就是这样。我会试试这个,稍后再回复你。
  • 嗯,这对我来说不太适用 - r.reading 的长度未定义。你究竟是如何打印出 json 的?
  • 因此,如果您使用我上面粘贴的 jsonifyObj 的代码,则相应的选择将是 SELECT obj FROM jsonifyObj(select r.Id, r.Reading.Raw from Example.TagRaw2 r)
  • 抱歉无法在工作之外访问此内容 - 我会尽快回复您
  • 您对输入格式的看法是正确的,但我仍然遇到问题。显然“长度”字段是未定义的。这是一个作业 ID:valued-vault-111213:job_-cWTofri5UVAkxNgSdnNzFSCHso
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-17
  • 1970-01-01
  • 1970-01-01
  • 2016-07-16
  • 2020-11-16
  • 1970-01-01
相关资源
最近更新 更多