How to query json field in Postgresql
February 3, 2026
·
2 min read
JSON 是一種常見的數據格式,Database 已經可以支援儲存同Query JSON 數據類型
今日就要係postgresql 度query 個 JSON field 睇返D log 同埋做返D data analysis
如何query JSON field in PostgreSQL 呢?
PostgreSQL 提供了兩個主要的操作符來查詢 JSON 數據:
->- 獲取 JSON 對象欄位(返回 JSON 類型)->>- 獲取 JSON 對象欄位(返回 TEXT 類型)
查詢範例
假設我們有一個 users 表,其中 profile 欄位是 JSONB 類型:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
profile JSONB
);
INSERT INTO users (name, profile) VALUES
('Alice', '{"age": 30, "city": "Hong Kong", "skills": ["JavaScript", "Python"]}'),
('Bob', '{"age": 25, "city": "Taipei", "skills": ["Java", "Go"]}');
1. 查詢特定欄位值
-- 使用 ->> 返回文本
SELECT name, profile->>'city' AS city FROM users;
-- 使用 -> 返回 JSON 對象
SELECT name, profile->'city' AS city FROM users;
2. WHERE 條件查詢
-- 查詢特定城市的使用者
SELECT * FROM users WHERE profile->>'city' = 'Hong Kong';
-- 數值比較(需要類型轉換)
SELECT * FROM users WHERE (profile->>'age')::int > 28;
3. 查詢嵌套 JSON
-- 嵌套對象查詢
INSERT INTO users (name, profile) VALUES
('Charlie', '{"age": 35, "address": {"street": "123 Main St", "district": "Central"}}');
SELECT name, profile->'address'->>'street' AS street FROM users;
4. 查詢 JSON 陣列
-- 檢查陣列中是否包含特定元素
SELECT * FROM users WHERE profile->'skills' ? 'JavaScript';
-- 獲取陣列中的特定索引(從 0 開始)
SELECT name, profile->'skills'->>0 AS first_skill FROM users;
5. 使用 JSON 函數
-- 獲取所有鍵
SELECT jsonb_object_keys(profile->'address') FROM users WHERE profile->'address' IS NOT NULL;
-- 檢查鍵是否存在
SELECT * FROM users WHERE profile ? 'skills';
-- 陣列長度
SELECT name, jsonb_array_length(profile->'skills') AS skill_count FROM users;
進階查詢:使用 JSON Path
PostgreSQL 12+ 支援 JSON Path 查詢:
-- 使用 jsonb_path_query
SELECT name, jsonb_path_query(profile, '$.city') AS city FROM users;
-- JSON Path 條件查詢
SELECT * FROM users WHERE jsonb_path_exists(profile, '$.age ? (@ > 28)');
建立索引提升效能
對於經常查詢的 JSON 欄位,可以建立索引:
-- GIN 索引適用於 JSONB
CREATE INDEX idx_users_city ON users USING GIN ((profile->'city'));
-- 或者使用表達式索引
CREATE INDEX idx_users_city_expr ON users ((profile->>'city'));
-- 為整個 JSONB 欄位建立索引
CREATE INDEX idx_users_profile ON users USING GIN (profile);
注意事項
- 使用
->>返回 TEXT,比較時可能需要類型轉換 JSONB會移除重複鍵和保留空白,但不保留鍵的順序- 大量數據查詢時,記得建立適當的索引
- 避免在 WHERE 條件中對整個 JSON 進行全文搜索,效能較差
Hope you find it useful!