在 jsonb 列上查询和计数
Query and count on jsonb column
我是 postgreSQL(9.5) Json 世界的新手。寻求编写此查询的帮助。以这个简化的table为例。
CREATE TABLE activity_log (uri varchar,
data jsonb );
'data' 列内的数据示例。
"{"ListingInputFilterBean":{"searchItems": [], "listingStatus": "ACTIVE"}"
"{"ListingInputFilterBean":{"searchItems": [{"name": "Dachshund", "type": "BREED"}], "listingStatus": "ACTIVE"}}"
"{"ListingInputFilterBean":{"searchItems": [{"name": "Lab", "type": "BREED"}, {"name": "Black Lab", "type": "CST"}], "listingStatus": "ACTIVE"}}"
'data' 列用于记录每个 URI 调用的特定数据集。在这种情况下,searchItems 数组包含搜索中使用的项目。我希望编写一个查询来查找搜索次数最多的 'breed'。当类型为 'BREED' 时,我想计算每个 'name' 被使用的次数。
我最初的方法是撤回每个 'searchItems'。使用 jsonb_to_recordset 将它们变成行集,但在阅读文档时我很快就陷入困境(抱歉,我是菜鸟)。
关于如何写 SQL 有什么建议吗?
WITH log_activity(data) AS ( VALUES
('{"ListingInputFilterBean":{"searchItems": [], "listingStatus": "ACTIVE"}}'::JSONB),
('{"ListingInputFilterBean":{"searchItems": [{"name": "Dachshund", "type": "BREED"}], "listingStatus": "ACTIVE"}}'::JSONB),
('{"ListingInputFilterBean":{"searchItems": [{"name": "Lab", "type": "BREED"}, {"name": "Black Lab", "type": "CST"}], "listingStatus": "ACTIVE"}}'::JSONB)
)
SELECT search_item->>'name',count(search_item->>'name')
FROM
log_activity la,
jsonb_array_elements(la.data#>'{ListingInputFilterBean,searchItems}') as search_item
WHERE search_item->>'type' = 'BREED'
GROUP BY search_item;
结果:
name | count
-----------+-------
Lab | 1
Dachshund | 1
(2 rows)
在这里您只需要遍历 searchItems
的列表并仅对那些符合您的条件的条目进行分组。步骤如下:
- 用
#>
运算符得到searchItems
的jsonb
数组,会得到指定路径下的JSON对象;
- 使用
jsonb_array_elements()
函数遍历步骤 1 中检索到的元素列表,该函数将 JSON 数组扩展为一组 JSON 值;
count()
names where searchItems' type
= BREED
, 你可以用 ->>
运算符得到实际的文本值;
更新
使用 jsonb_to_recordset()
看起来更短,但您需要明确定义 search_item
列的类型:
SELECT search_item.name ,count(search_item.name)
FROM
log_activity la,
jsonb_to_recordset(la.data#>'{ListingInputFilterBean,searchItems}') as search_item(name text,type text)
WHERE search_item.type = 'BREED'
GROUP BY search_item.name;
我是 postgreSQL(9.5) Json 世界的新手。寻求编写此查询的帮助。以这个简化的table为例。
CREATE TABLE activity_log (uri varchar,
data jsonb );
'data' 列内的数据示例。
"{"ListingInputFilterBean":{"searchItems": [], "listingStatus": "ACTIVE"}"
"{"ListingInputFilterBean":{"searchItems": [{"name": "Dachshund", "type": "BREED"}], "listingStatus": "ACTIVE"}}"
"{"ListingInputFilterBean":{"searchItems": [{"name": "Lab", "type": "BREED"}, {"name": "Black Lab", "type": "CST"}], "listingStatus": "ACTIVE"}}"
'data' 列用于记录每个 URI 调用的特定数据集。在这种情况下,searchItems 数组包含搜索中使用的项目。我希望编写一个查询来查找搜索次数最多的 'breed'。当类型为 'BREED' 时,我想计算每个 'name' 被使用的次数。
我最初的方法是撤回每个 'searchItems'。使用 jsonb_to_recordset 将它们变成行集,但在阅读文档时我很快就陷入困境(抱歉,我是菜鸟)。
关于如何写 SQL 有什么建议吗?
WITH log_activity(data) AS ( VALUES
('{"ListingInputFilterBean":{"searchItems": [], "listingStatus": "ACTIVE"}}'::JSONB),
('{"ListingInputFilterBean":{"searchItems": [{"name": "Dachshund", "type": "BREED"}], "listingStatus": "ACTIVE"}}'::JSONB),
('{"ListingInputFilterBean":{"searchItems": [{"name": "Lab", "type": "BREED"}, {"name": "Black Lab", "type": "CST"}], "listingStatus": "ACTIVE"}}'::JSONB)
)
SELECT search_item->>'name',count(search_item->>'name')
FROM
log_activity la,
jsonb_array_elements(la.data#>'{ListingInputFilterBean,searchItems}') as search_item
WHERE search_item->>'type' = 'BREED'
GROUP BY search_item;
结果:
name | count
-----------+-------
Lab | 1
Dachshund | 1
(2 rows)
在这里您只需要遍历 searchItems
的列表并仅对那些符合您的条件的条目进行分组。步骤如下:
- 用
#>
运算符得到searchItems
的jsonb
数组,会得到指定路径下的JSON对象; - 使用
jsonb_array_elements()
函数遍历步骤 1 中检索到的元素列表,该函数将 JSON 数组扩展为一组 JSON 值; count()
names where searchItems'type
=BREED
, 你可以用->>
运算符得到实际的文本值;
更新
使用 jsonb_to_recordset()
看起来更短,但您需要明确定义 search_item
列的类型:
SELECT search_item.name ,count(search_item.name)
FROM
log_activity la,
jsonb_to_recordset(la.data#>'{ListingInputFilterBean,searchItems}') as search_item(name text,type text)
WHERE search_item.type = 'BREED'
GROUP BY search_item.name;