2016-11-20 2 views
0

저는 PostgreSQL 9.5와 JSONB 데이터 형식을 사용하여 문서를 저장하고 있습니다. 이 같은 내 테이블 뭔가 : Postgres jsonb를 사용하여 배열 내에서 객체 값을 검색하려면 어떻게해야합니까?

create table records (
    id serial, 
    data jsonb 
); 

내 문서

예를 들어, 객체의 배열을 포함는 :

{ 
    "some_field": "a value", 
    "another_field": 123, 
    entries: [ 
    { 
     "name": "John Doe", 
     "age": 42 
    }, 
    { 
     "name": "Johnny McMuffin", 
     "age": 117 
    } 
    ] 
} 

문제는 내가 entriesname 속성을 필터링 할 수 있도록하고 싶습니다이다 배열 및 나는 그것을 알아낼 수 없다. 내 테이블에서 개체 목록의 이름 중 하나와 부분적으로 일치하는 행을 찾을 수 있기를 원합니다.

색인 및 표현식에 대해 많이 읽었지만 작동시키지 못했습니다. 이것이 가능하지 않아야합니까?

답변

1

그것은 예상 된 결과가 무엇인지 나에게 불분명하지만,이 같은 것이 작동합니다 :

select r.id, e.* 
from records r 
    cross join lateral jsonb_array_elements(r.data -> 'entries') as e 
where e ->> 'name' like '%Doe%'; 

당신에게 각 배열 요소에 액세스 할 수 있도록하기 위해이 "unnest"그들 (즉,이 정상화 할 필요가 정규화되지 않은 문서). 위의 예는 테이블의 각 행이 아닌 일치하는 배열 요소에 대해 하나의 행을 반환합니다. 당신이 기본 테이블에서 고유의 전체 행을해야 할 경우 당신은 또한 존재하는 하위 쿼리에 이름에 체크를 이동할 수 있습니다

:

select r.* 
from records r 
where exists (select 1 
      from jsonb_array_elements(r.data -> 'entries') as e 
      where e ->> 'name' like '%Doe%'); 

두 문장의 차이는, 그 첫 번째 쿼리 것입니다 당신은 당신에게 당신이 일치하는 배열 요소를 보여줄뿐입니다. 두 번째는 모두 적어도 하나의 일치하는 경우 문서의 배열 요소를 보여줍니다.

+0

이것은 작동하는 것 같습니다. 나는 가능한 복제본을 어떤 식 으로든 다룰 수 있다고 생각한다. – fiskeben

+0

이들은 중복되지 않습니다. 그것들은 배열의 다중 값입니다. 그러나'exists' 쿼리를 사용하여 기본 테이블에서 유일한 행을 얻을 수 있습니다. –

관련 문제