2012-11-28 26 views
11

में JSON ऑब्जेक्ट में तत्व जोड़ें मेरे पास एक डेटाबेस (पोस्टग्रेस 9.2.1) में एक टेक्स्ट फ़ील्ड है जिसमें एक जेसन ब्लॉब है। यह एक पंक्ति पर सभी को छोड़कर यह करने के लिए कुछ इसी तरह लग रहा है, जाहिर है:पोस्टग्रेस

{ 
    "keyword": { 
    "checked": "1", 
    "label": "Keyword" 
    }, 
    "something_new": { 
    "checked": "1", 
    "label": "Something New" 
    }, 
    "agency_name": { 
    "checked": "0", 
    "label": "Agency Name" 
    } 
} 

मैं के रूप में नहीं कर रहा हूँ:

{ 
    "keyword": { 
    "checked": "1", 
    "label": "Keyword" 
    }, 
    "agency_name": { 
    "checked": "0", 
    "label": "Agency Name" 
    } 
} 

मैं इतना है कि यह इस तरह दिखता है json सरणी के लिए एक तत्व जोड़ने की जरूरत नए सरणी तत्व की नियुक्ति के बारे में चिंतित। यह एजेंसी_नाम के बाद हो सकता है। क्या पोस्टग्रेज़ में ऐसा करने का कोई आसान तरीका है?

+1

http://stackoverflow.com/questions/10560394/how-do-i पढ़ने का प्रयास करें -उरी-यूज-फ़ील्ड-इन-द-न्यू-पोस्टग्रेस्क्ल-जेसन-डाटाटाइप। यह आपकी मदद कर सकता है। –

+0

डेटाबेस प्रशासक समूह –

उत्तर

5

पोस्टग्रेएसक्यूएल में अभी तक JSON समर्थन कार्यों के रास्ते में बहुत कुछ नहीं है: मैं देख सकता हूं कि array_to_json जैसे हैं, जो मूल JSON को सरणी में परिवर्तित करने के लिए एक समान तरीका था, जो तब उपयोगी हो सकता है, जिसे आप तब कर सकते थे जेएसओएन में कनवर्ट करने से पहले उस अतिरिक्त तत्व को जोड़ने के लिए हेरफेर करें।

शायद जेएसओएन में हेरफेर करने के लिए पीएल भाषा का उपयोग करना सबसे अच्छी बात है। एक स्पष्ट पीएलवी 8 होगा, जो PostgreSQL में जावास्क्रिप्ट प्रोग्रामिंग कार्यक्षमता प्रदान करता है। आप जावास्क्रिप्ट में एक उपयोगकर्ता परिभाषित समारोह जो JSON ब्लॉब तदनुसार हेरफेर होगा लिखना होगा:

बेशक

, जावा, पायथन या पर्ल की तरह कई अन्य पी एल भाषाओं बस के रूप में अच्छा हो सकता है JSON डेटा के साथ काम करना, और संभवतः आपके सिस्टम पर स्थापित करना आसान है। उपयोगकर्ता द्वारा परिभाषित कार्यों को इनमें से प्रत्येक में लिखा जा सकता है यदि आपने उन्हें सेट अप किया है।

+2

में स्पष्ट हो सकता है जाहिर है कि मैं जो जवाब चाहता था वह नहीं, लेकिन कम से कम कोई भी सहमत नहीं है। धन्यवाद। – thepriebe

1

संस्करण 9.5 create_missing = TRUE के साथ jsonb_set फ़ंक्शन प्रदान करता है। किसी अन्य मामलों में जोड़कर जानकारी के लिए निम्न हैक का उपयोग करें:

SELECT (trim(trailing '}' from data::text) || ', "c":2}')::json 

को जोड़ने के लिए/अधिक सही तरीके का उपयोग कर नए मूल्य की जगह:

UPDATE t 
SET data=t3.data 

FROM t AS t1 
INNER JOIN 
(
    SELECT id, json_object_agg(t.k,t.v) 
    FROM 
    (
     SELECT * 
     FROM (SELECT id, json_object_keys(data) as k, data->json_object_keys(data) as v FROM t) as t2 
     WHERE t.k != 'c' 

     UNION ALL 
     SELECT id, 'c'::text as k, '"new value"'::json as v FROM t1 
    ) as t3 
    GROUP by id 
) as t4 ON (t1.id=t4.id) 

कुंजी निकालने के लिए:

UPDATE t 
SET data=t3.data 

FROM t AS t1 
INNER JOIN 
(
    SELECT id, json_object_agg(t.k,t.v) 
    FROM (SELECT id, json_object_keys(data) as k, data->json_object_keys(data) as v FROM t) as t2 
    WHERE t.k != 'c' 
    GROUP by id 
) as t4 ON (t1.id=t4.id) 
+0

आपके उत्तर के लिए धन्यवाद। PostgreSQL 9.5 2 साल पहले मेरे लिए उपलब्ध नहीं था। तब से हमने JSON डेटाटाइप का उपयोग करना शुरू कर दिया है जो पोस्टग्रेस ऑफ़र करता है, और हम एन्कोड/डीकोड करने के लिए PHP का उपयोग करते हैं। जब जेएसओएन डीबी में सिर्फ एक स्ट्रिंग था तो उसने चीजों को थोड़ा कठिन बना दिया। – thepriebe

5

हैं पीजी 9.5.1 में अपग्रेड करें, फिर आप जेएसबीबी को मर्ज करने के लिए एसक्यूएल || संचालित कर सकते हैं, उदाहरण

select '{"a":1}'::jsonb || '{"a":2, "b":2}'::jsonb 

{"a": 2, "b": 2}

वापस आ जाएगी आप pg9.5.1 में नवीनीकृत नहीं कर सकते, IMHO, अपने कोड में काम कर रहे एक बेहतर विकल्प होगा। आप मानचित्र के रूप में पुरानी jsonb स्ट्रिंग को पार्स कर सकते हैं, और फिर मानचित्र को अपडेट कर सकते हैं, फिर स्ट्रिंग में कनवर्ट करें और डीबी-रिकॉर्ड अपडेट करें।

1

मुझे बिल्कुल यह समस्या थी। यह समाधान काफी 'शुद्ध' ऑब्जेक्ट मैनिपुलेशन है और मैं plpgsql को 'sql' कार्यों को पसंद करता हूं। आप एक रिकार्ड दे - - और फिर

CREATE OR REPLACE FUNCTION json_extend_object(
    input_object json, 
    append_key text, 
    append_object json) 
    RETURNS json AS 
$BODY$ 
    select json_object_agg (((json_val)::record).key, ((json_val)::record).value) 
    from (
     select json_val 
     from (select json_each (input_object) as json_val) disaggr 
     where ((json_val::record).key != append_key) 
     union 
     select newvals 
     from (
      select append_key, append_object 
     ) newvals 
    ) to_rows; 
$BODY$ 
    LANGUAGE sql IMMUTABLE 
    ; 
+0

दस्तावेज़ की शुरुआत में कैसे जोड़ा गया? – igilfanov

+0

'newvals' subquery और UNION को 'to_rows' subquery की 'select json_val' शाखा से पहले, इसके बजाए रखें। –

5

से एक रिकॉर्ड बनाया यहां तक ​​कि मैं एक ही समस्या थी, मैं गतिशील [] jsonb को नए तत्व संलग्न करने के लिए चाहता था मुख्य बात json_each का उपयोग कर disaggregate है।

मान लें column_jsonb [] = [{ "नाम": "xyz", "उम्र": "12"}]

UPDATE table_name 
    SET column_jsonb[] = array_append(column_jsonb[],'{"name":"abc","age":"22"}'); 

परिणाम: [{ "नाम": "xyz" , "आयु": "12"}, {"नाम": "एबीसी", "आयु": "22"}]

संबंधित मुद्दे