Làm thế nào để tạo một chỉ mục trên một thuộc tính json số nguyên trong postgres


7

Tôi không thể tìm ra cuộc sống của tôi làm thế nào để tạo một chỉ mục trên một thuộc tính của cột json của tôi là một số nguyên.

Tôi đã thử nó theo cách này (và hàng tá người khác)

CREATE INDEX user_reputation_idx ON users(("user"->>'reputation')::int)

Nó chỉ hoạt động tốt trong một truy vấn (ví dụ ORDER BY ("user"->>'reputation')::int)

Tôi đang thiếu gì?

CẬP NHẬT

Tôi đang gặp một lỗi cú pháp đơn giản, tuy nhiên, tôi thực sự không biết tại sao.

ERROR:  syntax error at or near "::"
LINE 1: ... user_reputation_idx ON users (("user"->>'reputation')::int)

Định nghĩa bảng khá đơn giản. Nó chỉ là một cột usercủa loại json.

Vì vậy, trông như thế này:

CREATE TABLE users
(
  "user" json
)

Bạn cần cung cấp thông báo lỗi nguyên văn và (phần có liên quan) định nghĩa bảng của bạn ( \d tbltrong psql), cũng như truy vấn bạn đang cố chạy. Đối với người mới bắt đầu, câu trả lời liên quan này về SO có thể giúp ích. Tuy nhiên, cái đó là để lập chỉ mục cho một mảng json . Trường hợp của bạn có vẻ đơn giản hơn ...
Erwin Brandstetter

1
Cám ơn bạn đã góp ý. Tôi biết câu trả lời khác đó và tôi đã sử dụng chỉ mục này cho các mảng như được mô tả ở đó thành công. Tôi cũng sử dụng một chỉ mục khác trên một jsontài sản giữ đơn giản text. Chỉ cho intcột này nó không hoạt động. Tuy nhiên, sử dụng nó trong một truy vấn để sắp xếp là inthoạt động tuyệt vời. Và btw, cảm ơn sự hỗ trợ tuyệt vời của bạn ở đây!
Christoph

Câu trả lời:


13

Hãy thử điều này thay thế:

CREATE INDEX user_reputation_idx ON users(cast("user"->>'reputation' AS int));

Các phím tắt Postgres cú pháp ::cho dàn diễn viên không được phép không có dấu ngoặc bổ sung trong một định nghĩa chỉ mục ( xem @ bình luận của BMA ). Mặc dù vậy, nó hoạt động với hàm SQL tiêu chuẩn: cast(expression AS type)Điều này không liên quan đến jsonkiểu per se.

Dù bằng cách nào, bạn vẫn có thể sử dụng phím tắt cú pháp expression::typetrong các biểu thức sử dụng chỉ mục.


Tuyệt quá! Điều đó đã làm việc. Chỉ có một dấu ngoặc đơn đóng trong truy vấn của bạn. Cảm ơn vì đã cứu ngày của tôi một lần nữa!
Christoph

5
Với đủ dấu ngoặc, nó sẽ hoạt động. Ví dụ CREATE INDEX user_reputation_idx2 ON users ( (("user"->>'reputation')::INT) ). Tôi nhớ lại việc đọc một câu trả lời trong danh sách pg nơi Tom Lane giải thích lý do tại sao biểu thức cần dấu ngoặc phụ, nhưng một tìm kiếm nhanh không bật lên được.
bma

0

Như @bma đã giải thích trong một nhận xét, chỉ mục của bạn sẽ hoạt động như bình thường, nếu bạn thêm dấu ngoặc kép xung quanh toàn bộ định nghĩa JSON:

CREATE INDEX user_reputation_idx ON users((("user"->>'reputation')::int));

Đảm bảo rằng bạn luôn sử dụng ký hiệu văn bản JSON [- >>], chứ không phải ký hiệu đối tượng JSON [->], trong chỉ mục và khi tham chiếu trường trong truy vấn hoặc chỉ mục sẽ không được sử dụng.

Ngoài ra, bạn luôn có thể sử dụng ký hiệu đối tượng [->]. Bạn chỉ cần dính vào cái này hay cái khác, đừng trộn chúng.

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.