কোনও পোস্টগ্রিস জেএসওন অ্যারেতে একটি স্ট্রিং রয়েছে কিনা তা পরীক্ষা করুন


119

আমার খরগোশ সম্পর্কে তথ্য সঞ্চয় করার জন্য আমার কাছে একটি টেবিল রয়েছে। দেখে মনে হচ্ছে:

create table rabbits (rabbit_id bigserial primary key, info json not null);
insert into rabbits (info) values
  ('{"name":"Henry", "food":["lettuce","carrots"]}'),
  ('{"name":"Herald","food":["carrots","zucchini"]}'),
  ('{"name":"Helen", "food":["lettuce","cheese"]}');

গাজর পছন্দ করে এমন খরগোশগুলিকে আমার কীভাবে খুঁজে পাওয়া উচিত? আমি এটি নিয়ে এসেছি:

select info->>'name' from rabbits where exists (
  select 1 from json_array_elements(info->'food') as food
  where food::text = '"carrots"'
);

আমি এই ক্যোয়ারী পছন্দ করি না। এটি একটি জগাখিচুড়ি.

পুরো সময়ের খরগোশ-রক্ষক হিসাবে আমার ডেটাবেস স্কিমা পরিবর্তন করার আমার কাছে সময় নেই। আমি কেবল আমার খরগোশগুলিকে সঠিকভাবে খাওয়াতে চাই। এই ক্যোয়ারীটি করার কি আরও পঠনযোগ্য উপায় আছে?


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

@ ডেভিডস: (আমি প্রশ্নটি আপডেট করেছি)) আমি দক্ষতার চেয়ে পঠনযোগ্যতা পছন্দ করব। আমি অবশ্যই পূর্ণ টেবিল স্ক্যানের চেয়ে ভাল কিছু আশা করি না, যেহেতু আমি স্কিমাটি স্থির করে রেখেছি।
স্নোবল

11
খরগোশের কারণে আমি কি এই প্রশ্নটিকে উড়িয়ে দিয়েছি?
ওসমান

3
আমি এই প্রশ্নটি খরগোশের কারণে সবেমাত্র উত্সাহিত করেছি এবং তারপরে আপনার মন্তব্যটি @ ইউসমান
1valdis

আমি আপনার মন্তব্যটি দেখেছি এবং বুঝতে পেরেছি খরগোশের কারণে আমার উর্ধ্বতন করা দরকার
পিটার আরন জেন্টাই

উত্তর:


184

PostgreSQL 9.4 হিসাবে, আপনি ?অপারেটরটি ব্যবহার করতে পারেন :

select info->>'name' from rabbits where (info->'food')::jsonb ? 'carrots';

আপনি যদি পরিবর্তে জসনব টাইপটিতে স্যুইচ করেন তবে আপনি কীটিতে? ক্যোয়ারীটি সূচক "food"করতে পারেন :

alter table rabbits alter info type jsonb using info::jsonb;
create index on rabbits using gin ((info->'food'));
select info->>'name' from rabbits where info->'food' ? 'carrots';

অবশ্যই, আপনার কাছে সম্ভবত একটি পূর্ণ-সময় খরগোশ রক্ষক হিসাবে সময় নেই।

আপডেট: এখানে 1,000,000 খরগোশের একটি টেবিলের পারফরম্যান্সের উন্নতির একটি প্রদর্শন রয়েছে যেখানে প্রতিটি খরগোশ দুটি খাবার পছন্দ করে এবং এর মধ্যে 10% গাজরের মতো করে:

d=# -- Postgres 9.3 solution
d=# explain analyze select info->>'name' from rabbits where exists (
d(# select 1 from json_array_elements(info->'food') as food
d(#   where food::text = '"carrots"'
d(# );
 Execution time: 3084.927 ms

d=# -- Postgres 9.4+ solution
d=# explain analyze select info->'name' from rabbits where (info->'food')::jsonb ? 'carrots';
 Execution time: 1255.501 ms

d=# alter table rabbits alter info type jsonb using info::jsonb;
d=# explain analyze select info->'name' from rabbits where info->'food' ? 'carrots';
 Execution time: 465.919 ms

d=# create index on rabbits using gin ((info->'food'));
d=# explain analyze select info->'name' from rabbits where info->'food' ? 'carrots';
 Execution time: 256.478 ms

জসনের অভ্যন্তরে খাদ্য অ্যারে খালি নয় এমন সারিগুলি কীভাবে পাবেন, উদাহরণস্বরূপ যদি আমরা বিবেচনা করতে পারি তবে সেগুলি জেএসএন, যেখানে খাদ্য অ্যারেও খালি রয়েছে, আপনি সহায়তা করতে পারেন
ব্র্যাভো

1
@ ব্রাভোselect * from rabbits where info->'food' != '[]';
স্নোবল

1
স্ট্রিং / পাঠ্যের পরিবর্তে আপনার পূর্ণসংখ্যা নির্বাচন করার ক্ষেত্রে এটি কীভাবে কাজ করে তা কি কেউ জানেন?
রোটেরেটি

3
@Rotareti আপনি ব্যবহার করতে পারেন @> অপারেটর : create table t (x jsonb); insert into t (x) values ('[1,2,3]'), ('[2,3,4]'), ('[3,4,5]'); select * from t where x @> '2';। নোট যে '2'একটি JSON নম্বর; উদ্ধৃতি দ্বারা বিভ্রান্ত করবেন না।
স্নোবল

@ স্নোবল, এই ক্যোয়ারীটি তথ্য নির্বাচন করুন - >> খরগোশ থেকে 'নাম' কোথায় (তথ্য -> 'খাবার') :: জসনব? 'গাজর'; JSON থেকে অনুসন্ধান শব্দটির জন্য নিখুঁতভাবে কাজ করছে working তবে আমি কীভাবে সমস্ত রেকর্ড পেতে পারি তাতে 'গাজর' শব্দটি থাকে না?
মিলান

23

আপনি @> অপারেটরটি এই জাতীয় কিছু করতে ব্যবহার করতে পারেন

SELECT info->>'name'
FROM rabbits
WHERE info->'food' @> '"carrots"';

1
আইটেমটি পাশাপাশি নাল হয়ে গেলে এটি কার্যকর
লুসিও

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

@ এসপিপ্লুনকারিন এটি 'স্ট্রিং গঠনের জন্য টিক্সের সাথে জড়িত জসন মান হওয়া উচিত , কারণ জেএসওএনবি টাইপের সমস্ত এসকিউএল এর স্ট্রিং। উদাহরণস্বরূপ, বুলিয়ান: 'true'স্ট্রিং: '"example"', পূর্ণসংখ্যা: '123'
1valdis

22

বুদ্ধিমান নয় বরং সহজ:

select info->>'name' from rabbits WHERE info->>'food' LIKE '%"carrots"%';

13

একটি ছোট প্রকরণ কিন্তু নতুন কিছুই নয়। এটি সত্যিই একটি বৈশিষ্ট্য অনুপস্থিত ...

select info->>'name' from rabbits 
where '"carrots"' = ANY (ARRAY(
    select * from json_array_elements(info->'food'))::text[]);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.