পোস্টগ্রিএসকিউএল-তে জসনব অ্যারে থেকে কীভাবে নির্দিষ্ট অবজেক্ট পাবেন?


16

আমার কাছে 'ব্যবহারকারী' নামক একটি ক্ষেত্র রয়েছে যা একটি জসন অ্যারে ধারণ করে যা দেখতে প্রায় দেখায়:

"user":

[{ "_id" : "1", "count" : "4" }, { "_id" : "3", "count": "4"}]

এখন আমি এই জাতীয় একটি কোয়েরি চাই:

select count from tablename where id = "1"

countপোস্টগ্র্রেএসকিউএল 9.4-এ জসন বস্তুর একটি অ্যারে থেকে আমি নির্দিষ্ট ক্ষেত্রটি পেতে সক্ষম নই ।

উত্তর:


17

আপনার মানগুলি একটি সাধারণীকৃত স্কিমাতে সঞ্চয় করা আরও বেশি দক্ষ হবে। এটি বলেছিল, আপনি এটি আপনার বর্তমান সেটআপ দিয়ে কাজ করতে পারেন।

অনুমিতি

এই সারণির সংজ্ঞাটি ধরে নেওয়া:

CREATE TABLE tbl (tbl_id int, usr jsonb);

"ব্যবহারকারী" একটি সংরক্ষিত শব্দ এবং কলামের নাম হিসাবে ডাবল উদ্ধৃতি ব্যবহার করতে হবে। এটা করবেন না। আমি usrপরিবর্তে ব্যবহার ।

প্রশ্ন

ক্যোয়ারী (এখন মুছে ফেলা) মন্তব্যগুলি দেখে মনে হচ্ছে তত তুচ্ছ নয়:

SELECT t.tbl_id, obj.val->>'count' AS count
FROM   tbl t
JOIN   LATERAL jsonb_array_elements(t.usr) obj(val) ON obj.val->>'_id' = '1'
WHERE  t.usr @> '[{"_id":"1"}]';

এখানে 3 টি প্রাথমিক পদক্ষেপ রয়েছে :

1. সস্তাভাবে যোগ্যতার সারিগুলি চিহ্নিত করুন

WHERE t.usr @> '[{"_id":"1"}]'জেএসওন অ্যারেতে মিল থাকা বস্তুর সাথে সারিগুলি সনাক্ত করে। অভিব্যক্তিটি jsonbকলামে জেনেরিক জিআইএন সূচক বা আরও বিশেষায়িত অপারেটর শ্রেণীর একটি ব্যবহার করতে পারে jsonb_path_ops:

CREATE INDEX tbl_usr_gin_idx ON tbl USING gin (usr jsonb_path_ops);

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

সম্পর্কিত:

2. অ্যারে ম্যাচিং অবজেক্ট (গুলি) সনাক্ত করুন

সাথে অযথা jsonb_array_elements()। ( unnest()পোস্টগ্র্রেস অ্যারে ধরণের ক্ষেত্রে কেবল ভাল)

সম্পর্কিত:

৩. নেস্টেড কীটির জন্য মান বের করুন 'count'

পরে কোয়ালিফাইং বস্তু নিষ্কাশিত করা হয়েছে, কেবল: obj.val->>'count'


2
কোথা obj(value)থেকে আসে? এটি কি LATERAL JOIN, jsonb_array_elementsঅন্য কোথাও?
টাইলার ডিউইট

দেখে মনে হচ্ছে ফর্ম্যাটিংটি খারাপ হয়ে গেছে। আমি কি এটি সঠিকভাবে পড়ছি JOIN LATERAL jsonb_array_elements(t.usr) obj(value) is short for JOIN LATERAL jsonb_array_elements(t.usr) AS obj(value)এবং এটি obj(value)একটি টেবিল এবং কলামের নাম? এই উদাহরণস্বরূপ, যদি objকোনও টেবিলের নাম হয় তবে এটি একটি উপনামটি কী? সেট থেকে ফিরে এসেছেন jsonb_array_elements?
টাইলার ডিউইট

1
হ্যাঁ, এবং হ্যাঁ আমি আমার স্ক্যাম্বলড মন্তব্য মুছে ফেলেছি।
এরউইন ব্র্যান্ডসেটেটার

কলামের নাম ব্যবহার করার দরকার আছে কি? আমার পরীক্ষায়, JOIN LATERAL jsonb_array_elements(t.usr) obj ON obj->>'_id' = '1'একই প্রভাব ছিল (একবার আপনি valueপরিবর্তে ব্যবহারের জন্য নির্বাচন বিবৃতি আপডেট করুন val)। এটি প্রদর্শিত হয় যে jsonb_array_elements(t.usr)কেবল একটি কলাম সহ একটি টেবিল ফেরত দেয়। পোস্টগ্রিস কি স্মার্ট হচ্ছে এবং বুঝতে পারছে যে obj ->>একই obj.val ->>?
টাইলার ডিউইট

কেবলমাত্র একটি একক কলাম সহ, পোস্টগ্রিস একটি প্রদত্ত ওরফে টেবিল এবং কলামের নাম হিসাবে ব্যবহার করে । আমি কেবল সুস্পষ্ট হয়েছি কারণ অনেকগুলি সেট-রিটার্নিং ফাংশন রয়েছে যা একাধিক কলামে ফিরে আসে।
এরউইন ব্র্যান্ডসেটেটার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.