将 JSON 加载到 bigquery - 字段有时是数组,有时是字符串

Posted

技术标签:

【中文标题】将 JSON 加载到 bigquery - 字段有时是数组,有时是字符串【英文标题】:Loading JSON to bigquery - field sometimes array and sometimes string 【发布时间】:2017-02-06 17:17:23 【问题描述】:

我正在尝试将 JSON 数据加载到 BigQuery。我的数据导致问题的摘录如下所示:

"page":"295"
"page":["295", "123"]

我已将此字段定义为:


  "name": "page",
  "type": "string",
  "mode": "repeated"

我收到“必须将重复字段作为 JSON 数组导入”的错误消息。我认为问题是由 JSON 本身的结构引起的。第一行中的字符串应该是一个元素数组,而不仅仅是一个字符串。数据是这样传递给我的。我正在尝试找到一种方法来强制 BigQuery 将此字符串作为一个元素数组读取,而不是修复文件(即数百 GB)。有什么解决办法吗?

【问题讨论】:

【参考方案1】:

一种选择是使用 BigQuery 来转换数据本身。假设您能够将行导入为 CSV(选择未出现在数据中的任意分隔符),您可以使用 JSON_EXTRACT 函数跨行检索 page 的值。例如,

#standardSQL
SELECT JSON_EXTRACT(json, '$.page') AS page
FROM UnprocessedTable;

之后您可以使用SPLIT 函数或REGEXP_EXTRACT_ALL 检索各个值。

编辑:作为一个具体的例子,你可以试试这个查询:

#standardSQL
WITH T AS (
  SELECT '"page": "foo"' AS json UNION ALL
  SELECT '"page": ["bar", "baz"]' AS json UNION ALL
  SELECT '"page": ["a", "b", "c"]' AS json
)
SELECT
  REGEXP_EXTRACT_ALL(JSON_EXTRACT(json, '$.page'), r'"([^"]*)"') AS pages
FROM T;

这会将 JSON 数组(或标量字符串)作为 ARRAY<STRING> 列返回。

【讨论】:

谢谢!这确实可能有效。问题是我的数据实际上包含 60 列。给定的示例只是导致问题的列。我应该早点提到它。我是否更正了在将整个数据集加载为 CSV 之后我需要单独提取每一列,即使是那些现在正常工作的列? 您可能会以编程方式生成查询,以便为其他每一列调用 JSON_EXTRACT_SCALAR。您应该至少只需要对数据执行一次此转换。 谢谢。另一个对我有用的解决方案是将整个数组 ["295", "123"] 作为字符串加载。这有可能吗?会不会容易些? 我认为您这样做可能还会出错,因为该类型将被声明为字符串,但您可以尝试一下。如果您能够将其作为字符串加载,则可以使用REGEXP_EXTRACT_ALL,如上例所示。 不幸的是,我无法将它简单地加载为可为空的字符串。 Array specified for non-repeated field 出现明显错误。有没有其他方法可以实现不包括将行导入为 CSV?

以上是关于将 JSON 加载到 bigquery - 字段有时是数组,有时是字符串的主要内容,如果未能解决你的问题,请参考以下文章

使用空字典作为值将 JSON 文件加载到 BigQuery

将 bigquery JSON 数据转储加载到 R tibble

BigQuery 加载 JSON 文件:如何忽略或重命名字段?

BigQuery:将 JSON 对象加载为字符串

BigQuery - 加载具有空值的 JSON 字段

使用 UI 将 JSON 加载到 Bigquery 时出错