Câu trả lời ngắn
Bạn có thể sử dụng hàm jsonb_array_elements()
trong một phép nối bên và sử dụng giá trị value
kết quả của nó trong các biểu thức phức tạp trong WHERE
mệnh đề:
SELECT t.*
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('b', 'd')
AND value->>'label1' IN ('2', '3')
Khác biệt
Truy vấn có thể trả về các hàng trùng lặp khi các điều kiện lọc được đáp ứng trong nhiều phần tử của mảng trong một hàng, ví dụ:
SELECT t.*
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')
id | test_content
--------------------------------------+----------------------------------------------------------------
aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | [{"label": "a", "label1": "1"}, {"label": "b", "label1": "2"}]
aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | [{"label": "a", "label1": "1"}, {"label": "b", "label1": "2"}]
(2 rows)
Do đó, có thể hợp lý khi sử dụng DISTINCT
trong SELECT
danh sách:
SELECT DISTINCT t.*
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')
hoặc EXISTS
trong WHERE
, có thể nhanh hơn một chút:
SELECT t.*
FROM test t
WHERE EXISTS (
SELECT
FROM jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')
)
Bạn cũng có thể chọn các phần tử mảng phù hợp trong các trường hợp cần thông tin này:
SELECT id, value
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')
id | value
--------------------------------------+-------------------------------
aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | {"label": "a", "label1": "1"}
aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | {"label": "b", "label1": "2"}
(2 rows)
Sự hoàn hảo
jsonb_array_elements()
chức năng đắt tiền. Đối với các bảng lớn hơn, việc sử dụng hàm có thể có vấn đề do tải nặng của máy chủ và thời gian thực thi truy vấn lâu.
Mặc dù chỉ mục GIN có thể được sử dụng cho các truy vấn với @>
nhà điều hành:
CREATE INDEX ON test USING GIN (test_content)
trong trường hợp của chức năng này là không thể. Các truy vấn được chỉ mục hỗ trợ có thể nhanh hơn tới vài chục lần so với các truy vấn sử dụng hàm.