Yeni PostgreSQL JSON veri türü içindeki alanları kullanarak nasıl sorgulayabilirim?


216

PostgreSQL 9.2 yeni JSON fonksiyonları için bazı belgeler ve / veya örnekler arıyorum.

Özellikle, bir dizi JSON kaydı verildi:

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

İsme göre bir kayıt bulmak için SQL'i nasıl yazarım?

Vanilya SQL'de:

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

Resmi dev el kitabı oldukça seyrek:

Güncelleme I

PostgreSQL 9.2 ile şu anda mümkün olanı açıklayan bir özeti bir araya getirdim . Bazı özel işlevleri kullanarak, aşağıdakileri yapmak mümkündür:

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

Güncelleme II

Şimdi JSON işlevlerimi kendi projelerine taşıdım:

PostSQL - PostgreSQL ve PL / v8'i tamamen harika bir JSON belge deposuna dönüştürmek için bir dizi işlev


3
Kısa bir süre önce Matt Schinckel tarafından hazırlanan ve PostgreSQL'deki JSON sorgulamasını ayrıntılı olarak açıklayan bu blog gönderisini buldum schinckel.net/2014/05/25/querying-json-in-postgres
knowbody

1
@knowbody Bu yazı aslında JSON'dan oldukça farklı olan JSONB'yi sorgulamakla ilgilidir. Gönderiyi daha açık hale getirmediğim için kötüyüm.
Matthew Schinckel

Yanıtlar:


177

Postgres 9.2

Ben alıntı pgsql-hacker listesinde Andrew Dunstan :

Bir aşamada muhtemelen bazı json-işleme (json-üretmenin aksine) fonksiyonlar olacaktır, ancak 9.2'de olmayacaktır.

PLV8'de sorununuzu çözmesi için örnek bir uygulama sağlamasını engellemez .

Postgres 9.3

"Json-işleme" eklemek için yeni fonksiyonlar ve operatörler cephanelik sunuyor.

Postgres 9.3'teki orijinal sorunun cevabı :

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

Gelişmiş örnek:

Daha büyük tablolar için performansı artırmak üzere bir ifade dizini eklemek isteyebilirsiniz:

Postgres 9.4

Ekler jsonb("ikili" için b, değerler yerel Postgres türleri olarak saklanır) ve her iki tür için de daha fazla işlevsellik . Yukarıda belirtilen ifade indekslerine ek olarak jsonb, GIN, btree ve hash indekslerini de destekler , GIN bunların en güçlü olanıdır.

Kılavuz şu kadar ileri gidiyor:

Genel olarak, çoğu uygulamajsonb nesne anahtarlarının sıralanması ile ilgili eski varsayımlar gibi oldukça özel ihtiyaçlar olmadığı sürece JSON verilerini depolamayı tercih etmelidir .

Cesur vurgu benim.

Performans, genel iyileştirmelerden GIN dizinlerine yararlanır.

Postgres 9.5

Komple jsonbfonksiyonlar ve operatörler. jsonbYerinde ve görüntülemek için daha fazla işlev ekleyin .


1
Teşekkürler, PLV8 yaklaşımını kullanarak çok hızlı yazım sorunları yaşadım. Umut verici görünüyor, ama şu anda gerçekten kullanışlı değil.
Toby Hede

@TobyHede: Sanırım 9.3'ü beklemek zorundayız.
Erwin Brandstetter

1
@JoeShaw: Teşekkürler, buna göre güncelledim ve Postgres Wiki'ye bir bağlantı ekledim.
Erwin Brandstetter

@ErwinBrandstetter NEREDE elem arıyorsanız - >> 'correct' = 'TRUE'; ve JSON şu şekilde görünür: "correct": "TRUE", mantıksal terimleri sorgulamanın doğru yolu nedir?
Ocak'ta Shiraj

@Shiraj: Lütfen yeni soruları soru olarak sorun . Yorumlar yer değil.
Erwin Brandstetter

87

Postgres 9.3+ ile ->operatörü kullanın . Örneğin,

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

bazı güzel örnekler ve eğitim için bkz. http://clarkdave.net/2013/06/what-can-you-do-with-postgresql-and-json/ .


2
Örnekte, adlı bir alan olmalıdır yukarıda databir JSON belgesiyle: {images:{thumbnail:{url:'thumbnail.jpg'}}}. Verilerinizin neye benzediğini ve hangi sorgunun başarısız olduğunu bize bildirin.
Meekohi


6
Bir dizi varsa nasıl sorgulayabilirsiniz? # >> operatörünü görüyorum ama nasıl kullanılacağına dair hiçbir ipucu yok!
Mohamed El Mahallawy

Bu seçme sorgusunda joker karakter kullanabilir miyim? IeSELECT data->'%'->'thumbnail'->'url' AS thumb FROM instagram;
Bharat

@ Meekohi'nin cevabı iyi çalışıyor: özellikle ::jsondiğer yazılarda açıklandığı gibi ihtiyacım yoktu . Ayrıca ->, var olmayan bir özelliğe erişmeye çalışırsanız (yani JSON'u sendelemişseniz) operatörün bir hata atacağını unutmayın :ERROR: column "jsonPropertyYouWant" does not exist
Kızıl Bezelye

19

Postgres 9.3 ile nesne erişimi için -> kullanın. 4 örnek

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

raylar c

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

İadeler

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

Yuvalamaya devam edebilirsiniz

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

dönüş

 data
------
 1
(1 row)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.