PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

मैं नए PostgreSQL JSON डेटाटाइप के अंदर फ़ील्ड को कैसे संशोधित करूं?

अपडेट करें :PostgreSQL 9.5 के साथ, कुछ jsonb हैं PostgreSQL के भीतर ही हेरफेर कार्यक्षमता (लेकिन json . के लिए कोई नहीं); json में हेरफेर करने के लिए कास्ट की आवश्यकता होती है मान)।

2 (या अधिक) JSON ऑब्जेक्ट (या श्रेणीबद्ध सरणियाँ) को मर्ज करना:

SELECT jsonb '{"a":1}' || jsonb '{"b":2}', -- will yield jsonb '{"a":1,"b":2}'
       jsonb '["a",1]' || jsonb '["b",2]'  -- will yield jsonb '["a",1,"b",2]'

तो, एक साधारण कुंजी सेट करना का उपयोग करके किया जा सकता है:

SELECT jsonb '{"a":1}' || jsonb_build_object('<key>', '<value>')

जहां <key> स्ट्रिंग होना चाहिए, और <value> to_jsonb() whatever किसी भी प्रकार का हो सकता है स्वीकार करता है।

एक JSON पदानुक्रम में गहरे मान को सेट करने के लिए , jsonb_set() फ़ंक्शन का उपयोग किया जा सकता है:

SELECT jsonb_set('{"a":[null,{"b":[]}]}', '{a,1,b,0}', jsonb '{"c":3}')
-- will yield jsonb '{"a":[null,{"b":[{"c":3}]}]}'

jsonb_set() . की पूरी पैरामीटर सूची :

jsonb_set(target         jsonb,
          path           text[],
          new_value      jsonb,
          create_missing boolean default true)

path इसमें JSON सरणी अनुक्रमणिका भी हो सकती है और नकारात्मक पूर्णांक जो वहां दिखाई देते हैं, उनकी गिनती JSON सरणियों के अंत से होती है। हालांकि, एक गैर-मौजूदा, लेकिन सकारात्मक JSON सरणी अनुक्रमणिका तत्व को सरणी के अंत में जोड़ देगी:

SELECT jsonb_set('{"a":[null,{"b":[1,2]}]}', '{a,1,b,1000}', jsonb '3', true)
-- will yield jsonb '{"a":[null,{"b":[1,2,3]}]}'

JSON सरणी में सम्मिलित करने के लिए (सभी मूल मानों को संरक्षित करते हुए) , jsonb_insert() फ़ंक्शन का उपयोग किया जा सकता है (9.6+ में; केवल यह फ़ंक्शन, इस अनुभाग में ):

SELECT jsonb_insert('{"a":[null,{"b":[1]}]}', '{a,1,b,0}', jsonb '2')
-- will yield jsonb '{"a":[null,{"b":[2,1]}]}', and
SELECT jsonb_insert('{"a":[null,{"b":[1]}]}', '{a,1,b,0}', jsonb '2', true)
-- will yield jsonb '{"a":[null,{"b":[1,2]}]}'

jsonb_insert() . की पूरी पैरामीटर सूची :

jsonb_insert(target       jsonb,
             path         text[],
             new_value    jsonb,
             insert_after boolean default false)

फिर से, नकारात्मक पूर्णांक जो path . में दिखाई देते हैं JSON सरणियों के अंत से गिनें।

तो, f.ex. JSON सरणी के अंत में संलग्न करके किया जा सकता है:

SELECT jsonb_insert('{"a":[null,{"b":[1,2]}]}', '{a,1,b,-1}', jsonb '3', true)
-- will yield jsonb '{"a":[null,{"b":[1,2,3]}]}', and

हालांकि, यह फ़ंक्शन थोड़ा अलग तरीके से काम कर रहा है (jsonb_set() . की तुलना में) ) जब path target . में JSON ऑब्जेक्ट की कुंजी है। उस स्थिति में, यह केवल JSON ऑब्जेक्ट के लिए एक नया की-वैल्यू पेयर जोड़ेगा जब कुंजी का उपयोग नहीं किया जाएगा। यदि इसका उपयोग किया जाता है, तो यह एक त्रुटि उत्पन्न करेगा:

SELECT jsonb_insert('{"a":[null,{"b":[1]}]}', '{a,1,c}', jsonb '[2]')
-- will yield jsonb '{"a":[null,{"b":[1],"c":[2]}]}', but
SELECT jsonb_insert('{"a":[null,{"b":[1]}]}', '{a,1,b}', jsonb '[2]')
-- will raise SQLSTATE 22023 (invalid_parameter_value): cannot replace existing key

कुंजी (या अनुक्रमणिका) हटाना JSON ऑब्जेक्ट से (या, किसी सरणी से) - . के साथ किया जा सकता है ऑपरेटर:

SELECT jsonb '{"a":1,"b":2}' - 'a', -- will yield jsonb '{"b":2}'
       jsonb '["a",1,"b",2]' - 1    -- will yield jsonb '["a","b",2]'

JSON पदानुक्रम में गहरे से हटाना #- . के साथ किया जा सकता है ऑपरेटर:

SELECT '{"a":[null,{"b":[3.14]}]}' #- '{a,1,b,0}'
-- will yield jsonb '{"a":[null,{"b":[]}]}'

9.4 के लिए , आप मूल उत्तर (नीचे) के संशोधित संस्करण का उपयोग कर सकते हैं, लेकिन JSON स्ट्रिंग को एकत्रित करने के बजाय, आप सीधे json_object_agg() के साथ एक json ऑब्जेक्ट में एकत्रित कर सकते हैं ।

मूल उत्तर :यह शुद्ध SQL में भी संभव है (बिना plpython या plv8 के) (लेकिन 9.3+ की जरूरत है, 9.2 के साथ काम नहीं करेगा)

CREATE OR REPLACE FUNCTION "json_object_set_key"(
  "json"          json,
  "key_to_set"    TEXT,
  "value_to_set"  anyelement
)
  RETURNS json
  LANGUAGE sql
  IMMUTABLE
  STRICT
AS $function$
SELECT concat('{', string_agg(to_json("key") || ':' || "value", ','), '}')::json
  FROM (SELECT *
          FROM json_each("json")
         WHERE "key" <> "key_to_set"
         UNION ALL
        SELECT "key_to_set", to_json("value_to_set")) AS "fields"
$function$;

SQLFiddle

संपादित करें :

एक संस्करण, जो कई कुंजियाँ और मान सेट करता है:

CREATE OR REPLACE FUNCTION "json_object_set_keys"(
  "json"          json,
  "keys_to_set"   TEXT[],
  "values_to_set" anyarray
)
  RETURNS json
  LANGUAGE sql
  IMMUTABLE
  STRICT
AS $function$
SELECT concat('{', string_agg(to_json("key") || ':' || "value", ','), '}')::json
  FROM (SELECT *
          FROM json_each("json")
         WHERE "key" <> ALL ("keys_to_set")
         UNION ALL
        SELECT DISTINCT ON ("keys_to_set"["index"])
               "keys_to_set"["index"],
               CASE
                 WHEN "values_to_set"["index"] IS NULL THEN 'null'::json
                 ELSE to_json("values_to_set"["index"])
               END
          FROM generate_subscripts("keys_to_set", 1) AS "keys"("index")
          JOIN generate_subscripts("values_to_set", 1) AS "values"("index")
         USING ("index")) AS "fields"
$function$;

2 संपादित करें :जैसा कि @ErwinBrandstetter ने उपरोक्त कार्यों को एक तथाकथित UPSERT की तरह नोट किया है (यदि कोई फ़ील्ड मौजूद है तो अपडेट करता है, यदि वह मौजूद नहीं है तो सम्मिलित करता है)। यहाँ एक प्रकार है, जो केवल UPDATE है :

CREATE OR REPLACE FUNCTION "json_object_update_key"(
  "json"          json,
  "key_to_set"    TEXT,
  "value_to_set"  anyelement
)
  RETURNS json
  LANGUAGE sql
  IMMUTABLE
  STRICT
AS $function$
SELECT CASE
  WHEN ("json" -> "key_to_set") IS NULL THEN "json"
  ELSE (SELECT concat('{', string_agg(to_json("key") || ':' || "value", ','), '}')
          FROM (SELECT *
                  FROM json_each("json")
                 WHERE "key" <> "key_to_set"
                 UNION ALL
                SELECT "key_to_set", to_json("value_to_set")) AS "fields")::json
END
$function$;

3 संपादित करें :यहां पुनरावर्ती संस्करण है, जो सेट कर सकता है (UPSERT ) एक लीफ वैल्यू (और इस उत्तर से पहले फ़ंक्शन का उपयोग करता है), एक की-पथ पर स्थित है (जहाँ कुंजियाँ केवल आंतरिक वस्तुओं को संदर्भित कर सकती हैं, आंतरिक सरणियाँ समर्थित नहीं हैं):

CREATE OR REPLACE FUNCTION "json_object_set_path"(
  "json"          json,
  "key_path"      TEXT[],
  "value_to_set"  anyelement
)
  RETURNS json
  LANGUAGE sql
  IMMUTABLE
  STRICT
AS $function$
SELECT CASE COALESCE(array_length("key_path", 1), 0)
         WHEN 0 THEN to_json("value_to_set")
         WHEN 1 THEN "json_object_set_key"("json", "key_path"[l], "value_to_set")
         ELSE "json_object_set_key"(
           "json",
           "key_path"[l],
           "json_object_set_path"(
             COALESCE(NULLIF(("json" -> "key_path"[l])::text, 'null'), '{}')::json,
             "key_path"[l+1:u],
             "value_to_set"
           )
         )
       END
  FROM array_lower("key_path", 1) l,
       array_upper("key_path", 1) u
$function$;

अपडेट किया गया:मौजूदा जेसन फ़ील्ड की कुंजी को किसी अन्य दी गई कुंजी से बदलने के लिए जोड़ा गया फ़ंक्शन। माइग्रेशन या डेटा संरचना में संशोधन जैसे अन्य परिदृश्यों में डेटा प्रकारों को अपडेट करने के लिए उपयोगी हो सकता है।

CREATE OR REPLACE FUNCTION json_object_replace_key(
    json_value json,
    existing_key text,
    desired_key text)
  RETURNS json AS
$BODY$
SELECT COALESCE(
(
    SELECT ('{' || string_agg(to_json(key) || ':' || value, ',') || '}')
    FROM (
        SELECT *
        FROM json_each(json_value)
        WHERE key <> existing_key
        UNION ALL
        SELECT desired_key, json_value -> existing_key
    ) AS "fields"
    -- WHERE value IS NOT NULL (Actually not required as the string_agg with value's being null will "discard" that entry)

),
    '{}'
)::json
$BODY$
  LANGUAGE sql IMMUTABLE STRICT
  COST 100;

अपडेट करें :फ़ंक्शन अब संकुचित हो गए हैं।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. स्मॉलिंट [] कॉलम पर GIN इंडेक्स इस्तेमाल नहीं किया गया या एरर ऑपरेटर यूनिक नहीं है

  2. PostgreSQL में बल्क/बैच अपडेट/अपर्ट

  3. PHP और पोस्टग्रेस:​​त्रुटियों को पकड़ना?

  4. GIS:PostGIS/PostgreSQL बनाम MySql बनाम SQL सर्वर?

  5. कैसे Statement_timestamp () PostgreSQL में काम करता है