Làm cách nào để truy vấn bằng cách sử dụng các trường bên trong kiểu dữ liệu JSON PostgreSQL mới?


216

Tôi đang tìm kiếm một số tài liệu và / hoặc ví dụ cho các hàm JSON mới trong PostgreQuery 9.2.

Cụ thể, đưa ra một loạt các bản ghi JSON:

[
  {name: "Toby", occupation: "Software Engineer"},
  {name: "Zaphod", occupation: "Galactic President"}
]

Làm thế nào tôi có thể viết SQL để tìm một bản ghi theo tên?

Trong vanilla SQL:

SELECT * from json_data WHERE "name" = "Toby"

Hướng dẫn sử dụng dev chính thức khá thưa thớt:

Cập nhật tôi

Tôi đã tập hợp một ý chính chi tiết những gì hiện có thể có với PostgreSQL 9.2 . Sử dụng một số chức năng tùy chỉnh, có thể thực hiện những việc như:

SELECT id, json_string(data,'name') FROM things
WHERE json_string(data,'name') LIKE 'G%';

Cập nhật II

Bây giờ tôi đã chuyển các hàm JSON của mình vào dự án của riêng họ:

PostQuery - một tập hợp các hàm để chuyển đổi PostgreSQL và PL / v8 thành một kho tài liệu JSON hoàn toàn tuyệt vời


3
Gần đây tôi đã tìm thấy bài đăng trên blog này của Matt Schinckel, trong đó giải thích chi tiết về truy vấn JSON trong PostgreQuery schinckel.net/2014/05/25/querying-json-in-postgres
knowbody 27/11/14

1
@ Recognbody Bài đăng này thực sự là về truy vấn JSONB, khá khác biệt so với JSON. Xấu của tôi vì đã không làm cho điều đó rõ ràng hơn trong bài viết.
Matthew Schinckel

Câu trả lời:


177

Hậu 9,2

Tôi xin trích lời Andrew Dunstan thuộc danh pgsql-hacker :

Ở giai đoạn nào đó có thể sẽ có một số chức năng xử lý json (trái ngược với chức năng sản xuất json), nhưng không phải trong 9.2.

Không ngăn anh ta cung cấp một triển khai ví dụ trong PLV8 sẽ giải quyết vấn đề của bạn.

Hậu 9,3

Cung cấp một kho các chức năng và toán tử mới để thêm "xử lý json".

Câu trả lời cho câu hỏi ban đầu trong Postgres 9.3:

SELECT *
FROM   json_array_elements(
  '[{"name": "Toby", "occupation": "Software Engineer"},
    {"name": "Zaphod", "occupation": "Galactic President"} ]'
  ) AS elem
WHERE elem->>'name' = 'Toby';

Ví dụ nâng cao:

Đối với các bảng lớn hơn, bạn có thể muốn thêm chỉ mục biểu thức để tăng hiệu suất:

Hậu 9,4

Thêm jsonb(b cho "nhị phân", các giá trị được lưu trữ dưới dạng các loại Postgres gốc) và nhiều chức năng hơn cho cả hai loại. Ngoài các chỉ mục biểu thức được đề cập ở trên, jsonbcũng hỗ trợ các chỉ mục GIN, btree và băm , GIN là mạnh nhất trong số này.

Hướng dẫn đi xa như đề xuất:

Nói chung, hầu hết các ứng dụng nên lưu trữ dữ liệu JSON jsonb , trừ khi có các nhu cầu khá chuyên biệt, chẳng hạn như các giả định kế thừa về việc sắp xếp các khóa đối tượng.

Nhấn mạnh đậm của tôi.

Hiệu suất lợi ích từ những cải tiến chung cho các chỉ số GIN.

Hậu 9,5

Hoàn thành các jsonbchức năng và toán tử. Thêm nhiều chức năng để thao tác jsonbtại chỗ và để hiển thị.


1
Cảm ơn, tôi đã gặp vấn đề về loại rất nhanh khi sử dụng phương pháp PLV8. Có vẻ đầy hứa hẹn, nhưng không thực sự có thể sử dụng tại thời điểm này.
Toby Hede

@TobyHede: Đoán chúng ta sẽ phải đợi 9.3 rồi.
Erwin Brandstetter

1
@JoeShaw: Cảm ơn, tôi đã cập nhật tương ứng và thêm một liên kết đến Postgres Wiki.
Erwin Brandstetter

@ErwinBrandstetter nếu tôi đang tìm kiếm WHERE elem - >> 'chính xác' = 'TRUE'; và JSON trông như thế này: "chính xác": "TRUE", cách đúng để truy vấn các thuật ngữ logic là gì?
Shiraj

@Shiraj: Hãy đặt câu hỏi mới dưới dạng câu hỏi . Bình luận không phải là nơi.
Erwin Brandstetter

87

Với Postgres 9.3+, chỉ cần sử dụng ->toán tử. Ví dụ,

SELECT data->'images'->'thumbnail'->'url' AS thumb FROM instagram;

xem http://clarkdave.net/2013/06/what-can-you-do-with-postgresql-and-json/ để biết một số ví dụ hay và hướng dẫn.


2
Trong ví dụ trên, bạn nên có một trường có tên là datatài liệu JSON : {images:{thumbnail:{url:'thumbnail.jpg'}}}. Hãy cho chúng tôi biết dữ liệu của bạn trông như thế nào và truy vấn nào bị lỗi.
Meekohi


6
Làm thế nào bạn có thể truy vấn nếu có một mảng? Tôi thấy toán tử # >> nhưng không biết cách sử dụng!
Mohamed El Mahallawy

Trong truy vấn chọn này, tôi có thể sử dụng ký tự đại diện không? Tức làSELECT data->'%'->'thumbnail'->'url' AS thumb FROM instagram;
Bharat

Câu trả lời của @ Meekohi hoạt động tốt: cụ thể là tôi không cần ::jsonnhư mô tả trong các bài viết khác. Cũng lưu ý rằng ->nhà điều hành sẽ đưa ra lỗi nếu bạn cố truy cập vào một thuộc tính không tồn tại (nghĩa là nếu bạn đã sử dụng JSON so le):ERROR: column "jsonPropertyYouWant" does not exist
The Red Pea

19

Với postgres 9.3 sử dụng -> để truy cập đối tượng. 4 ví dụ

hạt giống.rb

se = SmartElement.new
se.data = 
{
    params:
    [
        {
            type: 1,
            code: 1,
            value: 2012,
            description: 'year of producction'
        },
        {
            type: 1,
            code: 2,
            value: 30,
            description: 'length'
        }
    ]
}

se.save

đường ray c

SELECT data->'params'->0 as data FROM smart_elements;

trả lại

                                 data
----------------------------------------------------------------------
 {"type":1,"code":1,"value":2012,"description":"year of producction"}
(1 row)

Bạn có thể tiếp tục làm tổ

SELECT data->'params'->0->'type' as data FROM smart_elements;

trở về

 data
------
 1
(1 row)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.