查询 Postgres 9.6 JSONB 对象数组
Querying Postgres 9.6 JSONB array of objects
我有以下 table:
CREATE TABLE trip
(
id SERIAL PRIMARY KEY ,
gps_data_json jsonb NOT NULL
);
gps_data_json 中的 JSON 包含一组具有以下字段的旅行对象(下面的示例数据):
- 模式
- 时间戳
- 纬度
- 经度
我正在尝试获取包含特定 "mode" 的所有行。
SELECT * FROM trip
where gps_data_json ->> 'mode' = 'WALK';
我很确定我用错了 ->> 运算符,但我不确定该告诉查询 JSONB 字段是一个对象数组吗?
示例数据:
INSERT INTO trip (gps_data_json) VALUES
('[
{
"latitude": 47.063480377197266,
"timestamp": 1503056880725,
"mode": "TRAIN",
"longitude": 15.450349807739258
},
{
"latitude": 47.06362533569336,
"timestamp": 1503056882725,
"mode": "WALK",
"longitude": 15.450264930725098
}
]');
INSERT INTO trip (gps_data_json) VALUES
('[
{
"latitude": 47.063480377197266,
"timestamp": 1503056880725,
"mode": "BUS",
"longitude": 15.450349807739258
},
{
"latitude": 47.06362533569336,
"timestamp": 1503056882725,
"mode": "WALK",
"longitude": 15.450264930725098
}
]');
出现问题是因为->>
运算符无法遍历数组:
- 首先使用
json_array_elements
函数取消嵌套您的 json 数组;
- 然后使用运算符进行过滤
以下查询可以解决问题:
WITH
A AS (
SELECT
Id
,jsonb_array_elements(gps_data_json) AS point
FROM trip
)
SELECT *
FROM A
WHERE (point->>'mode') = 'WALK';
如果您只想包含查询值的对象,取消数组嵌套效果很好。
以下检查包含和 returns 完整的 JSONB:
SELECT * FROM trip
WHERE gps_data_json @> '[{"mode": "WALK"}]';
另见
select * from
(select id, jsonb_array_elements(gps_data_json) point from trip where id = 16) t
where point @> '{"mode": "WALK"}';
在我的 Table 中,id = 16
是为了确保特定行仅是 jsonb-array 数据类型。由于其他行数据只是 JSONB 对象。所以你必须首先过滤掉 jsonb-array 数据。否则:ERROR: cannot extract elements from an object
我有以下 table:
CREATE TABLE trip
(
id SERIAL PRIMARY KEY ,
gps_data_json jsonb NOT NULL
);
gps_data_json 中的 JSON 包含一组具有以下字段的旅行对象(下面的示例数据):
- 模式
- 时间戳
- 纬度
- 经度
我正在尝试获取包含特定 "mode" 的所有行。
SELECT * FROM trip
where gps_data_json ->> 'mode' = 'WALK';
我很确定我用错了 ->> 运算符,但我不确定该告诉查询 JSONB 字段是一个对象数组吗?
示例数据:
INSERT INTO trip (gps_data_json) VALUES
('[
{
"latitude": 47.063480377197266,
"timestamp": 1503056880725,
"mode": "TRAIN",
"longitude": 15.450349807739258
},
{
"latitude": 47.06362533569336,
"timestamp": 1503056882725,
"mode": "WALK",
"longitude": 15.450264930725098
}
]');
INSERT INTO trip (gps_data_json) VALUES
('[
{
"latitude": 47.063480377197266,
"timestamp": 1503056880725,
"mode": "BUS",
"longitude": 15.450349807739258
},
{
"latitude": 47.06362533569336,
"timestamp": 1503056882725,
"mode": "WALK",
"longitude": 15.450264930725098
}
]');
出现问题是因为->>
运算符无法遍历数组:
- 首先使用
json_array_elements
函数取消嵌套您的 json 数组; - 然后使用运算符进行过滤
以下查询可以解决问题:
WITH
A AS (
SELECT
Id
,jsonb_array_elements(gps_data_json) AS point
FROM trip
)
SELECT *
FROM A
WHERE (point->>'mode') = 'WALK';
如果您只想包含查询值的对象,取消数组嵌套效果很好。 以下检查包含和 returns 完整的 JSONB:
SELECT * FROM trip
WHERE gps_data_json @> '[{"mode": "WALK"}]';
另见
select * from
(select id, jsonb_array_elements(gps_data_json) point from trip where id = 16) t
where point @> '{"mode": "WALK"}';
在我的 Table 中,id = 16
是为了确保特定行仅是 jsonb-array 数据类型。由于其他行数据只是 JSONB 对象。所以你必须首先过滤掉 jsonb-array 数据。否则:ERROR: cannot extract elements from an object