避免 BigQuery 中 JSON_EXTRACT 函数中的指数表示法
Posted
技术标签:
【中文标题】避免 BigQuery 中 JSON_EXTRACT 函数中的指数表示法【英文标题】:avoiding exponential notation in JSON_EXTRACT function in BigQuery 【发布时间】:2015-10-22 10:27:09 【问题描述】:我正在使用 BigQuery 并将 JSON 字符串存储在某些字段中。 在这里,我有一个名为“json”的字段,其中包含如下 JSON 字符串:
"log_id":939286972300751993,"status":"good"
并使用下面的 sql 查询:
SELECT json, JSON_EXTRACT(json, "$.log_id") AS log_id
FROM dataset.table;
结果是:
json | log_id
-------------------------------------------------+---------------------
"log_id": 939286972300751993, "status": "good" | 9.39286972300752e+17
但我期望的是:
json | log_id
-------------------------------------------------+---------------------
"log_id": 939286972300751993, "status": "good" | 939286972300751993
"log_id" 在我的上下文中应该被视为 INTEGER。 有什么办法可以避免 JSON_EXTRACT 函数将大整数替换为指数符号?
【问题讨论】:
据我所知,JSON 规范没有对数字范围施加任何限制,但大多数库确实有限制。如果您切换到字符串,您可能会更安全:"log_id":"939286972300751993","status":"good"
感谢重播。是的,我认为你是对的。如果我可以重新定义架构,我会按照你说的做,但我已经拥有包含数据的庞大数据集,正如我所解释的,很难更新所有数据。
你如何抛出你的查询?通过 GUI,通过 API?
我尝试了 Web GUI 和 API,结果是一样的。
【参考方案1】:
您可以在查询本身中将结果转换为 INTEGER。
SELECT json, INTEGER(JSON_EXTRACT(json, "$.log_id")) AS log_id
FROM dataset.table;
正如您问题的 cmets 中所述,在 JSON 中存储大量数字可能会导致您丢失任何超过 2^53 的数字的精度(在 http://rfc7159.net/rfc7159 中搜索“数字”)。如果发生这种情况,JSON 解析库本身就会丢失精度,因此在查询的其他地方强制转换为 INTEGER(或进行一些 API 级别的更改)将无济于事。
【讨论】:
我明白这一点。谢谢你的详细解释。【参考方案2】:我同意 @jeremy-condit 和 @Álvaro-gonzález 关于存储大量数字的观点,但有时您无法更改所提供的数据。..
作为将JSON_EXTRACT
结果转换为整数导致空值的答案,我使用了regexp_extract
。
虽然不是最好的方法,但这可能对其他人有用:
SELECT json, integer(regexp_extract(json, "\"log_id\":([0-9]*),")) as log_id
FROM dataset.table;
【讨论】:
以上是关于避免 BigQuery 中 JSON_EXTRACT 函数中的指数表示法的主要内容,如果未能解决你的问题,请参考以下文章
将 BigQuery 表导出到 Google Storage 时如何避免标头
如何在 BigQuery SQL 中使用 UNNEST 和 SPLIT 避免重复?
使用 google bigquery API 时避免 DefaultCredentialsError