अपडेट करें :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;
अपडेट करें :फ़ंक्शन अब संकुचित हो गए हैं।