我最近考虑将我们的产品数据库从mongo迁移到postgres。来自mongoDb,我习惯于"放松"对象和数组。
假设您有以下对象:
{
"styleGroupId": "2",
"brand": "MOP",
"colorVariants": [
{
"color": "red",
"colorCode": "222",
"sizeVariants": [
{"gtin": "444",
"size": "M"},
{"gtin": "555",
"size": "L"}
]
},
{
"color": "blue",
"colorCode": "111",
"sizeVariants": [
{"gtin": "66",
"size": "M"},
{"gtin": "77",
"size": "L"}
]
}
]
}
如果你想展平它,在mongo中使用以下内容:
db.test.aggregate([
{
$unwind: "$colorVariants"
},
{
$unwind: "$colorVariants.sizeVariants"
}
])
将产生如下对象:
{
"_id" : ObjectId("5a7dc59dafc86d25964b873c"),
"styleGroupId" : "2",
"brand" : "MOP",
"colorVariants" : {
"color" : "red",
"colorCode" : "222",
"sizeVariants" : {
"gtin" : "444",
"size" : "M"
}
}
}
我花了几个小时寻找" mongo在postgres"但几乎找不到令人满意的答案。在postgres中查询JSONB数据的很多资源几乎都没有触及嵌套数组。希望这篇文章能帮助其他可怜的灵魂寻找从mongoDb到postgres的迁移。
答案 0 :(得分:1)
功能:
create or replace function jsonb_unwind(target jsonb, path text[])
returns jsonb language plpgsql as $$
begin
if jsonb_typeof(target #> path) = 'array' then
return jsonb_set(target, path, target #> path -> 0);
else
return target;
end if;
end $$;
使用示例:
select
jsonb_unwind(
jsonb_unwind(json_data, '{colorVariants}'),
'{colorVariants, sizeVariants}')
from my_table;
答案 1 :(得分:0)
在这篇文章中可以隐含地找到答案:How to query nested arrays in a postgres json column?
修改强>
与此回答配对use - to remove a key from a JSONB 从9.6
开始,有一种更简单的方法可以让你更接近mongo放松FROM
子句中声明每个数组级别将对象与共享键连接时,只保留||
运算符右侧对象的键
-
SELECT
data::jsonb - 'colorVariants' ||
colorVariants.* - 'sizeVariants' ||
sizeVariants.*
FROM
test,
jsonb_array_elements(data -> 'colorVariants') colorVariants,
jsonb_array_elements(colorVariants -> 'sizeVariants') sizeVariants;
结果就是
?column?
-------------------------------------------------------------------------------------------------------
{"gtin": "11", "size": "M", "brand": "MOP", "color": "red", "colorCode": "222", "styleGroupId": "1"}
{"gtin": "22", "size": "L", "brand": "MOP", "color": "red", "colorCode": "222", "styleGroupId": "1"}
{"gtin": "33", "size": "M", "brand": "MOP", "color": "blue", "colorCode": "111", "styleGroupId": "1"}
{"gtin": "44", "size": "L", "brand": "MOP", "color": "blue", "colorCode": "111", "styleGroupId": "1"}
{"gtin": "444", "size": "M", "brand": "MOP", "color": "red", "colorCode": "222", "styleGroupId": "2"}
{"gtin": "555", "size": "L", "brand": "MOP", "color": "red", "colorCode": "222", "styleGroupId": "2"}
{"gtin": "66", "size": "M", "brand": "MOP", "color": "blue", "colorCode": "111", "styleGroupId": "2"}
{"gtin": "77", "size": "L", "brand": "MOP", "color": "blue", "colorCode": "111", "styleGroupId": "2"}
旧帖子
FROM
子句中声明每个数组级别colorVariants
嵌套数组也将被返回因此,在特定情况下,解决方案将是:
SELECT
data->'brand' as brand,
data->'styleGroupId' as styleGroupId,
colorVariants->'color' as color,
colorVariants->'colorCode' as colorCode,
sizeVariants->'gtin' as GTIN,
sizeVariants->'size' as size
FROM
test,
jsonb_array_elements(data->'colorVariants') colorVariants,
jsonb_array_elements(colorVariants->'sizeVariants') sizeVariants
将导致
brand | stylegroupid | color | colorcode | gtin | size
-------+--------------+--------+-----------+-------+------
"MOP" | "1" | "red" | "222" | "11" | "M"
"MOP" | "1" | "red" | "222" | "22" | "L"
"MOP" | "1" | "blue" | "111" | "33" | "M"
"MOP" | "1" | "blue" | "111" | "44" | "L"
"MOP" | "2" | "red" | "222" | "444" | "M"
"MOP" | "2" | "red" | "222" | "555" | "L"
"MOP" | "2" | "blue" | "111" | "66" | "M"
"MOP" | "2" | "blue" | "111" | "77" | "L"