如何将JSON字符串列行转换为可查询表
Posted
技术标签:
【中文标题】如何将JSON字符串列行转换为可查询表【英文标题】:How to convert JSON string column row into a queriable table 【发布时间】:2020-05-29 13:26:27 【问题描述】:因此,我已将整个集合从 Firestore 导出到 BigQuery,以对其执行某些查询。
在我的 BigQuery 控制台中填充数据后,现在我可以像这样查询整个集合
SELECT * FROM `myapp-1a602.firestore_orders.orders_raw_changelog` LIMIT 1000
现在,这条语句抛出了我的不同列,但我要查找的是数据列,在我的数据列中是每个文档 JSON,但是是 json 格式,我需要查询所有这些值。
现在,这是一行的数据
"cart": [
"qty": 1,
"description": "Sprite 1 L",
"productName": "Sprite 1 Liter",
"price": 1.99,
"productId": 9
],
"storeName": "My awesome shop",
"status": 5,
"timestamp":
"_seconds": 1590713204,
"_nanoseconds": 916000000
这个数据在 data 列中,所以如果我这样做
SELECT data FROM `myapp-1a602.firestore_orders.orders_raw_changelog` LIMIT 1000
我将获取每个文档的所有 json 值,但我不知道如何查询这些值,假设我想知道所有具有 status 5 和 shopName My awesome shop 的订单,现在,我需要用这个 json 做点什么来把它转换成一个表吗?我需要在 json 本身中执行查询吗?
如何查询这个 json 输出?
谢谢
【问题讨论】:
【参考方案1】:我需要用这个 json 做点什么来把它转换成一个表吗?我需要在 json 本身中执行查询吗?
以下是 BigQuery 标准 SQL
#standardSQL
SELECT * EXCEPT(data, cart_item),
JSON_EXTRACT(data, '$.status') AS status,
JSON_EXTRACT(data, '$.storeName') AS storeName,
JSON_EXTRACT(cart_item, '$.qty') AS qty,
JSON_EXTRACT(cart_item, '$.description') AS description,
JSON_EXTRACT(cart_item, '$.productName') AS productName,
JSON_EXTRACT(cart_item, '$.price') AS price,
JSON_EXTRACT(cart_item, '$.productId') AS productId
FROM `project.dataset.table`,
UNNEST(JSON_EXTRACT_ARRAY(data, '$.cart')) cart_item
如果应用到您的问题中的样本数据,如下例所示
#standardSQL
WITH `project.dataset.table` AS (
SELECT 1 order_id, '''
"cart": [
"qty": 1,
"description": "Sprite 1 L",
"productName": "Sprite 1 Liter",
"price": 1.99,
"productId": 9
,
"qty": 2,
"description": "Fanta 1 L",
"productName": "Fanta 1 Liter",
"price": 1.99,
"productId": 10
],
"storeName": "My awesome shop",
"status": 5,
"timestamp":
"_seconds": 1590713204,
"_nanoseconds": 916000000
''' data
)
SELECT * EXCEPT(data, cart_item),
JSON_EXTRACT(data, '$.status') AS status,
JSON_EXTRACT(data, '$.storeName') AS storeName,
JSON_EXTRACT(cart_item, '$.qty') AS qty,
JSON_EXTRACT(cart_item, '$.description') AS description,
JSON_EXTRACT(cart_item, '$.productName') AS productName,
JSON_EXTRACT(cart_item, '$.price') AS price,
JSON_EXTRACT(cart_item, '$.productId') AS productId
FROM `project.dataset.table`,
UNNEST(JSON_EXTRACT_ARRAY(data, '$.cart')) cart_item
结果是
Row order_id status storeName qty description productName price productId
1 1 5 "My awesome shop" 1 "Sprite 1 L" "Sprite 1 Liter" 1.99 9
2 1 5 "My awesome shop" 2 "Fanta 1 L" "Fanta 1 Liter" 1.99 10
【讨论】:
【参考方案2】:您可以使用 json 函数,例如
CrEATE Table products (id Integer,attribs_json JSON );
INSERT INTO products VALUES (1,' "cart": [ "qty": 1, "description": "Sprite 1 L", "productName": "Sprite 1 Liter", "price": 1.99, "productId": 9 ], "storeName": "My awesome shop", "status": 5, "timestamp": "_seconds": 1590713204, "_nanoseconds": 916000000 ');
编号 | attribs_json -: | :------------------------------------------------ -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------- 1 | "cart": ["qty": 1, "price": 1.99, "productId": 9, "description": "Sprite 1 L", "productName": "Sprite 1 Liter"], "status" : 5, "storeName": "My awesome shop", "timestamp": "_seconds": 1590713204, "_nanoseconds": 916000000select * from products where attribs_json->"$.status" = 5 AND attribs_json->"$.storeName" = 'My awesome shop';
db小提琴here
attribs_json->"$.storeName" | attribs_json->"$.status" | attribs_json->"$.cart[0].qty" :---------------------------- | :------------------------ | :---------------------------- “我的好店” | 5 | 1select attribs_json->"$.storeName",attribs_json->"$.status",attribs_json->"$.cart[0].qty" from products where attribs_json->"$.status" = 5 AND attribs_json->"$.storeName" = 'My awesome shop';
db小提琴here
还有JSON_EXTRACT 用于mysql 5.7 及更高版本。
最后只有文字,所以你也可以使用REGEXP or RLIKE
要将 jaso 再次转移到行,您可以使用 JSON_TABLE
【讨论】:
我的想法是我不想只分析这个json,有400行这种 你可以看看dev.mysql.com/doc/refman/8.0/en/json-table-functions.html o 还添加了一个查询,该查询将来自该 jsona 的数据作为行和列提供给您【参考方案3】:您必须做的是从 json 数据中提取值: 选择 ....... WHERE data->'$.storeName'= "My awesome shop" and data->'$.status' = 5
从 'cart' 或 'timestamp' 键中提取将为您提供一个 Json 对象,该对象需要进一步提取以获取数据。 我希望它会帮助你 您可能想查看 MySql 文档 (https://dev.mysql.com/doc/refman/8.0/en/json.html) 或 https://www.mysqltutorial.org/mysql-json/。
【讨论】:
【参考方案4】:您可以在 WHERE 子句中使用 UNNEST 来访问购物车的列,并在 WHERE 子句中使用 JSON_EXTRACT 函数来过滤所需的行。您需要注意访问 json 根目录或数组 cart
; json_data
和 cart_items
在下面的示例中(顺便说一下,在您的示例中 shopName
不存在,但 storeName
存在)。
WITH
`myapp-1a602.firestore_orders.orders_raw_changelog` AS (
SELECT
'"cart": ["qty": 1,"description": "Sprite 1 L","productName": "Sprite 1 Liter","price": 1.99,"productId": 9, "qty": 11,"description": "Sprite 11 L","productName": "Sprite 11 Liter","price": 11.99,"productId": 19],"storeName": "My awesome shop","status": 5,"timestamp": "_seconds": 1590713204,"_nanoseconds": 916000000' json_data )
SELECT
JSON_EXTRACT(json_data, '$.status') AS status,
JSON_EXTRACT(json_data, '$.storeName') AS storeName,
JSON_EXTRACT(cart_items, '$.productName') AS product,
JSON_EXTRACT_SCALAR(cart_items, '$.qty') AS qty
FROM
`myapp-1a602.firestore_orders.orders_raw_changelog`,
UNNEST(JSON_EXTRACT_ARRAY(json_data, '$.cart')) AS cart_items
WHERE
JSON_EXTRACT(json_data,'$.storeName') like "\"My awesome shop\"" AND
CAST(JSON_EXTRACT_SCALAR(json_data,'$.status') AS NUMERIC) = 5
【讨论】:
但是通过这种方式,我可以只从那个特定的 json 中提取数据,我希望它可以在所有数据库中使用 select WITH 子句仅用于解释目的,它旨在演示如何根据您共享的 json 文档进行查询(根据您的 cmets,它是一行)。您应该使用具有 json 文档的表更改 FROM 子句并删除 WITH 子句,我已更新我的回复以使用表 firestore_orders.orders_raw_changelog 代替,但您的问题的解决方案是其他答案中解释的提取函数。以上是关于如何将JSON字符串列行转换为可查询表的主要内容,如果未能解决你的问题,请参考以下文章
使用 SQL 将字符串列转换为 mongodb 中的日期时间
使用 objection.js 或 knex.js 在 postgres 中的字符串列的 json 数组中查询