পোস্টগ্রিসএসকিউএল রিটার্ন ফলাফল JSON অ্যারে হিসাবে সেট?


134

আমি পোস্টগ্রিসএসকিউএলকে একটি জেএসওন অ্যারে হিসাবে কোনও প্রশ্নের ফলাফল ফিরিয়ে দিতে চাই। প্রদত্ত

create table t (a int primary key, b text);

insert into t values (1, 'value1');
insert into t values (2, 'value2');
insert into t values (3, 'value3');

আমি এর মতো কিছু চাই

[{"a":1,"b":"value1"},{"a":2,"b":"value2"},{"a":3,"b":"value3"}]

অথবা

{"a":[1,2,3], "b":["value1","value2","value3"]}

(আসলে এটি উভয়ই জানতে আরও কার্যকর হবে)। আমি কিছু জিনিস চেষ্টা করেছি

select row_to_json(row) from (select * from t) row;
select array_agg(row) from (select * from t) row;
select array_to_string(array_agg(row), '') from (select * from t) row;

এবং আমি অনুভব করি যে আমি নিকটেই আছি, তবে আসলে সেখানে নেই। আমি 9.15 ব্যতীত অন্যান্য ডকুমেন্টেশন খুঁজছি উচিত JSON কার্যাবলী এবং অপারেটর ?

যাইহোক, আমি আমার ধারণা সম্পর্কে নিশ্চিত নই। এটি কি সাধারণ নকশার সিদ্ধান্ত? আমার চিন্তাভাবনাটি হ'ল আমি অবশ্যই উপরের 3 টি প্রশ্নের প্রথমটির ফলাফল (উদাহরণস্বরূপ) নিতে এবং এটি ক্লায়েন্টের কাছে পরিবেশন করার আগে অ্যাপ্লিকেশনটিতে সামান্য হেরফের করতে পারি, তবে যদি পোস্টগ্রিসএসকিউএল সরাসরি চূড়ান্ত জেএসএন অবজেক্ট তৈরি করতে পারে, এটি সহজ হবে, কারণ আমি এখনও আমার আবেদনে কোনও জেএসএন লাইব্রেরির উপর নির্ভরশীলতা অন্তর্ভুক্ত করি নি।


1
পিজি 9.4, এখন বিটা 1 রিলিজে উপলভ্য, বাইনারি আই / ও সহ জেএসএনের পক্ষে সমর্থন উন্নত করেছে। আপনি যদি কোনও উন্নয়ন মেশিনে থাকেন তবে আপনি এটি পরীক্ষা করে দেখতে চাইতে পারেন।
প্যাট্রিক

@ পেট্রিক: আপনাকে ধন্যবাদ, দেখে মনে হচ্ছে এটি জেসন_বজেক্ট () 9.4-এ একটি নতুন ফাংশন এবং আমি সেফেক্ট জসন_বজেক্ট (অ্যারে_অ্যাগ (টা), অ্যারে_অ্যাগ (টিবি)) এর মতো কিছু চেষ্টা করবো, যদি আমার কাছে থাকে
ইঞ্জিনিয়ারএক্স

উত্তর:


266

টি এল; ডিআর

SELECT json_agg(t) FROM t

JSON অ্যারে অবজেক্টের জন্য এবং

SELECT
    json_build_object(
        'a', json_agg(t.a),
        'b', json_agg(t.b)
    )
FROM t

অ্যারেগুলির JSON অবজেক্টের জন্য।

বস্তুর তালিকা

এই বিভাগটি বর্ণনা করে যে কীভাবে JSON অ্যারে অবজেক্ট তৈরি করা যায়, প্রতিটি সারি একক বস্তুতে রূপান্তরিত হয়। ফলাফলটি এরকম দেখাচ্ছে:

[{"a":1,"b":"value1"},{"a":2,"b":"value2"},{"a":3,"b":"value3"}]

9.3 এবং উপরে

json_aggফাংশন বাক্সের বাইরে এই ফলাফল উৎপন্ন হয়। এটি স্বয়ংক্রিয়ভাবে কীভাবে এর ইনপুটটিকে JSON এ রূপান্তর করতে পারে এবং এটিকে একটি অ্যারেতে সংযুক্ত করে।

SELECT json_agg(t) FROM t

এর কোনও jsonbসংস্করণ (9.4 তে প্রবর্তিত) নেই json_agg। আপনি হয় সারিগুলিকে একটি অ্যারে রূপান্তর করতে পারেন এবং তারপরে সেগুলি রূপান্তর করতে পারেন:

SELECT to_jsonb(array_agg(t)) FROM t

বা json_aggকাস্টের সাথে একত্রিত করুন :

SELECT json_agg(t)::jsonb FROM t

আমার পরীক্ষাটি পরামর্শ দেয় যে এগুলিকে প্রথমে অ্যারেতে একত্রিত করা কিছুটা দ্রুত। আমার সন্দেহ হয় যে এটি হ'ল কারণ কাস্টটিকে পুরো জেএসএন ফলাফল পার্স করতে হয়েছে।

9.2

9.2 এর json_aggবা to_jsonকার্যকারিতা নেই, তাই আপনাকে পুরানোটি ব্যবহার করতে হবে array_to_json:

SELECT array_to_json(array_agg(t)) FROM t

আপনি কোয়েরিতে row_to_jsonকলটি অন্তর্ভুক্ত করতে পারেন :

SELECT array_to_json(array_agg(row_to_json(t))) FROM t

এটি প্রতিটি সারি একটি JSON অবজেক্টে রূপান্তর করে, JSON অবজেক্টগুলিকে একটি অ্যারে হিসাবে একত্রিত করে এবং তারপরে অ্যারেটিকে JSON অ্যারে রূপান্তর করে।

আমি দুজনের মধ্যে কোনও উল্লেখযোগ্য পারফরম্যান্সের পার্থক্য বুঝতে সক্ষম হয়েছি।

তালিকার অবজেক্ট

এই বিভাগটি কীভাবে একটি JSON অবজেক্ট তৈরি করবেন তা বর্ণনা করে, প্রতিটি কীটি টেবিলের কলাম এবং প্রতিটি মান কলামের মানগুলির অ্যারে হয়। এটি ফলাফল যা দেখতে এই রকম:

{"a":[1,2,3], "b":["value1","value2","value3"]}

9.5 এবং উপরে

আমরা json_build_objectফাংশনটি কাজে লাগাতে পারি :

SELECT
    json_build_object(
        'a', json_agg(t.a),
        'b', json_agg(t.b)
    )
FROM t

আপনি একক সারি তৈরি করে কলামগুলিও একত্রিত করতে পারেন এবং তারপরে এটিকে কোনও বস্তুতে রূপান্তর করতে পারেন:

SELECT to_json(r)
FROM (
    SELECT
        json_agg(t.a) AS a,
        json_agg(t.b) AS b
    FROM t
) r

নোট করুন যে অ্যারেগুলি অ্যালিজ করাতে অবজেক্টের পছন্দসই নাম রয়েছে তা নিশ্চিত করার জন্য একেবারে প্রয়োজনীয়।

কোনটি পরিষ্কার তা মতের একটি বিষয়। যদি ব্যবহার করেjson_build_object ফাংশনটি আমি পঠনযোগ্যতা উন্নত করতে একটি কী / মান জোড়কে একটি লাইনে রাখার পরামর্শ দিচ্ছি।

আপনি array_aggএর জায়গায়ও ব্যবহার করতে পারেন json_agg, তবে আমার পরীক্ষাটি নির্দেশ করে যে json_aggএটি কিছুটা দ্রুত।

ফাংশনের কোনও jsonbসংস্করণ নেই json_build_object। আপনি একক সারিতে সামগ্রিকভাবে রূপান্তর করতে পারেন:

SELECT to_jsonb(r)
FROM (
    SELECT
        array_agg(t.a) AS a,
        array_agg(t.b) AS b
    FROM t
) r

এই জাতীয় ফলাফলের জন্য অন্যান্য প্রশ্নের বিপরীতে, array_aggব্যবহার করার সময় কিছুটা দ্রুত বলে মনে হচ্ছে to_jsonb। আমি সন্দেহ করি যে এটি ওভারহেড পার্সিং এবং এর জেএসওএন ফলাফলকে বৈধতার কারণে json_agg

অথবা আপনি একটি সুস্পষ্ট কাস্ট ব্যবহার করতে পারেন:

SELECT
    json_build_object(
        'a', json_agg(t.a),
        'b', json_agg(t.b)
    )::jsonb
FROM t

to_jsonbসংস্করণ আমার পরীক্ষাকার্যের অনুযায়ী, আপনি ঢালাই এড়াতে পারবেন এবং দ্রুত হয়; আবার, আমি সন্দেহ করি যে এটি ফলাফলকে বৈধকরণ এবং বৈধকরণের ওভারহেডের কারণে।

9.4 এবং 9.3

json_build_objectফাংশন 9.5 কাছে নতুন ছিল, তাই আপনি পূর্ববর্তী সংস্করণে উপস্থিত অবজেক্টে সমষ্টিগত এবং রূপান্তর করতে হবে:

SELECT to_json(r)
FROM (
    SELECT
        json_agg(t.a) AS a,
        json_agg(t.b) AS b
    FROM t
) r

অথবা

SELECT to_jsonb(r)
FROM (
    SELECT
        array_agg(t.a) AS a,
        array_agg(t.b) AS b
    FROM t
) r

যদি আপনি চান কিনা তার উপর নির্ভর করে jsonবা jsonb

(9.3 আছে না jsonb।)

9.2

9.2 সালে, এমনকি to_jsonবিদ্যমান নেই। আপনি অবশ্যই ব্যবহার করুন row_to_json:

SELECT row_to_json(r)
FROM (
    SELECT
        array_agg(t.a) AS a,
        array_agg(t.b) AS b
    FROM t
) r

নথিপত্র

মধ্যে তাদেরকে JSON কাজকর্মের জন্য ডকুমেন্টেশন খুঁজুন তাদেরকে JSON ফাংশন

json_aggচালু রয়েছে সমষ্টিগত ফাংশন পাতা।

নকশা

যদি পারফরম্যান্স গুরুত্বপূর্ণ হয় তবে আমার পরীক্ষার উপর নির্ভর না করে আপনার নিজের স্কিমা এবং ডেটার বিরুদ্ধে প্রশ্নগুলি বেঞ্চমার্ক নিশ্চিত করুন।

এটি একটি ভাল নকশা হোক বা না হোক তা আপনার নির্দিষ্ট প্রয়োগের উপর নির্ভর করে। রক্ষণাবেক্ষণের ক্ষেত্রে, আমি কোনও বিশেষ সমস্যা দেখছি না। এটি আপনার অ্যাপ্লিকেশন কোডটিকে সহজতর করে এবং এর অর্থ অ্যাপ্লিকেশনটির সেই অংশটি বজায় রাখার কম রয়েছে। পিজি যদি আপনাকে বাক্সের বাইরে ঠিক মতো ফলাফল দিতে পারে তবে আমি এটি ব্যবহার না করার জন্য কেবলমাত্র কারণটি পারফরম্যান্স বিবেচনার বিবেচনা করতে পারি। চাকা এবং সব পুনরায় উদ্ভাবন করবেন না।

NULLs

সমষ্টিগত ক্রিয়াকলাপগুলি সাধারণত NULLযখন তারা শূন্যের চেয়ে বেশি সারি পরিচালনা করে তখন ফিরিয়ে দেয় । যদি এটির সম্ভাবনা থাকে তবে COALESCEএগুলি এড়াতে আপনি ব্যবহার করতে পারেন । উদাহরণ দুটি:

SELECT COALESCE(json_agg(t), '[]'::json) FROM t

অথবা

SELECT to_jsonb(COALESCE(array_agg(t), ARRAY[]::t[])) FROM t

ক্রেডিট Hannes Landeholm জন্য এই ইশারা


3
আপনার উত্তর করার জন্য আপনাকে ধন্যবাদ। আপনি আমার দ্বিতীয় প্রশ্নের উত্তর সন্ধান করতে আমাকে অনুপ্রাণিত করেছেন, সারি নির্বাচন_রো_জসন (সারি (অ্যারে_এজিজি (টা), অ্যারে_এজিজি (টিবি)), যদিও ফলাফলটি "এফ 1" এবং "এফ 2" লেবেল হিসাবে a এবং খ এর পরিবর্তে রয়েছে।
ইঞ্জিনিয়ারএক্স

@ ইঞ্জিনিয়ারএক্স আমি আমার উত্তরটি প্রসারিত করেছি।
jpmc26

3
অভ্যন্তরীণ নির্বাচনটি (টি থেকে) শূন্য সারিতে ফিরে আসার পরে কোনও খালি JSON অ্যারের পরিবর্তে NULL ফিরে পাওয়া কিছু ক্ষেত্রে এটি অনাকাঙ্ক্ষিত হতে পারে। এটি সামগ্রিক ফাংশনগুলির দ্বারা সর্বদা NULL ফেরার কারণে ঘটে যখন কোনও সারি ছাড়াই নির্বাচন করা হয় এবং কোলেসেসের দ্বারা সমাধানযোগ্য হয় না: অ্যারে_ট_জসন (কোলেসেস (অ্যারে_অ্যাগ (টি), অ্যারে [] :: রেকর্ড []))।
হ্যানস ল্যান্ডহোম

3
আপনি ব্যবহার করতে পারেন to_jsonপরিবর্তে row_to_jsonএবংarray_to_json
itsnikolay

(একাধিক) নির্দিষ্ট কলামগুলি নির্বাচন করতে আপনাকে এগুলি একটি একক যুক্তি হিসাবে পাস করতে হবে - একটি বৃত্তাকার বন্ধনী তালিকার মতো SELECT json_agg((column1, column2, ...)) FROM t - অতিরিক্ত বন্ধনীগুলি লক্ষ্য করুন। এটি "বাক্সের বাইরে" সুস্পষ্ট নাও হতে পারে।
jave.web

19

এছাড়াও আপনি যদি টেবিল থেকে নির্বাচিত ক্ষেত্রটি চান এবং অ্যারে হিসাবে সম্মিলিত হন।

SELECT json_agg(json_build_object('data_a',a,
                                  'data_b',b,
))  from t;

ফলাফল আসবেই।

 [{'data_a':1,'data_b':'value1'}
  {'data_a':2,'data_b':'value2'}]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.