새로운 PostgreSQL JSON 데이터 유형의 필드를 사용하여 쿼리하려면 어떻게합니까?


216

PostgreSQL 9.2의 새로운 JSON 함수에 대한 문서 및 / 또는 예제를 찾고 있습니다.

특히 일련의 JSON 레코드가 주어진 경우 :

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

이름으로 레코드를 찾기 위해 SQL을 작성하는 방법은 무엇입니까?

바닐라 SQL에서 :

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

공식 개발자 매뉴얼은 매우 드물다.

업데이트 I

내가 조립 한 PostgreSQL을 9.2으로 현재 무엇이 가능한지 자세히 요점을 . 일부 사용자 정의 기능을 사용하면 다음과 같은 작업을 수행 할 수 있습니다.

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

업데이트 II

이제 JSON 함수를 자체 프로젝트로 옮겼습니다.

PostSQL -PostgreSQL 및 PL / v8을 완전히 멋진 JSON 문서 저장소로 변환하는 기능 세트


3
최근에 나는 PostgreSQL을에 JSON 질의에 대해 자세히 설명 매트 Schinckel에 의해이 블로그 게시물을 발견 schinckel.net/2014/05/25/querying-json-in-postgres
knowbody

1
@knowbody이 게시물은 실제로 JSONB와 관련이있는 JSONB 쿼리에 관한 것입니다. 게시물에서 더 명확하게하지 않은 것에 대한 나의 나쁜.
Matthew Schinckel

답변:


177

포스트그레스 9.2

pgsql-hackers 목록에서 Andrew Dunstan을 인용 합니다 .

어떤 단계에서는 (json-producing과 반대되는) json-processing 기능이있을 수 있지만 9.2에는 없습니다.

PLV8에서 구현 예제 를 제공하는 것을 방해하지 않습니다. 문제를 해결 .

포스트그레스 9.3

"json-processing"을 추가 할 수있는 새로운 기능과 연산자를 제공합니다.

Postgres 9.3 의 원래 질문대한 답변 :

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

고급 예 :

더 큰 테이블의 경우 성능을 높이기 위해 표현식 색인을 추가 할 수 있습니다.

포스트그레스 9.4

추가 jsonb( "이진"의 경우, 값은 기본 Postgres 유형으로 저장 됨) 및 유형 모두에 대해 더 많은 기능성 . 위에서 언급 한 표현식 인덱스 외에도 GIN, btree 및 해시 인덱스를jsonb 지원하며 , GIN이 가장 강력합니다.

매뉴얼은 다음과 같이 제안합니다.

일반적으로 객체 키 순서에 대한 레거시 가정과 같은 특수한 요구가없는 한 대부분의 응용 프로그램은 JSON 데이터를로 저장하는 것을 선호해야합니다 jsonb .

대담한 강조 광산.

GIN 지수의 일반적인 개선으로 성능이 향상됩니다.

포스트그레스 9.5

완벽한 jsonb기능과 연산자. jsonb제자리 에서 조작 하고 표시 하기 위해 더 많은 기능을 추가하십시오 .


1
고마워, 나는 PLV8 접근 방식을 사용하여 실제로 유형 문제를 빨리 겪었습니다. 유망 해 보이지만 현재는 실제로 사용할 수 없습니다.
Toby Hede

@TobyHede : 그때 우리는 9.3을 기다려야 할 것 같아요.
Erwin Brandstetter

1
@JoeShaw : 감사합니다. 이에 따라 업데이트하고 Postgres Wiki에 대한 링크를 추가했습니다.
Erwin Brandstetter

내가 어디에서 찾고 있다면 @ ErwinBrandstetter elem->> 'correct'= 'TRUE'; JSON은 "correct": "TRUE"와 같이 논리적 용어를 쿼리하는 올바른 방법은 무엇입니까?
Shiraj

@Shiraj : 새로운 질문을 질문하십시오 . 의견은 장소가 아닙니다.
Erwin Brandstetter

87

Postgres 9.3+에서는 ->연산자를 사용하십시오 . 예를 들어

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

좋은 예와 자습서는 http://clarkdave.net/2013/06/what-can-you-do-with-postgresql-and-json/ 을 참조 하십시오 .


2
위의 예 data에서 JSON 문서로 이름이 지정된 필드가 있어야합니다 {images:{thumbnail:{url:'thumbnail.jpg'}}}. 데이터의 모양과 실패한 쿼리를 알려주십시오.
Meekohi


6
배열이 있는지 어떻게 쿼리 할 수 ​​있습니까? # >> 연산자가 있지만 사용법에 대한 실마리는 없습니다!
Mohamed El Mahallawy

이 쿼리에서 와일드 카드를 사용할 수 있습니까? 즉SELECT data->'%'->'thumbnail'->'url' AS thumb FROM instagram;
Bharat

@Meekohi의 대답은 잘 작동합니다. 특히 ::json다른 게시물에 설명 된 것처럼 필요하지 않았습니다 . 또한 ->존재하지 않는 속성에 액세스하려고하면 (예 : JSON을 엇갈리게 한 경우) 운영자가 오류를 발생시킵니다.ERROR: column "jsonPropertyYouWant" does not exist
The Red Pea

19

postgres 9.3에서는 객체 액세스에->를 사용하십시오. 4 예

seed.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

레일 c

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

보고

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

중첩을 계속할 수 있습니다

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

반환

 data
------
 1
(1 row)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.