jsonb
पोस्टग्रेज में 9.4+
बाइनरी JSON डेटा प्रकार jsonb
सूचकांक विकल्पों में काफी सुधार करता है। अब आपके पास jsonb
. पर GIN इंडेक्स हो सकता है सीधे सरणी:
CREATE TABLE tracks (id serial, artists jsonb); -- !
CREATE INDEX tracks_artists_gin_idx ON tracks USING gin (artists);
सरणी को बदलने के लिए किसी फ़ंक्शन की आवश्यकता नहीं है। यह एक प्रश्न का समर्थन करेगा:
SELECT * FROM tracks WHERE artists @> '[{"name": "The Dirty Heads"}]';
@>
jsonb
होने के नाते "शामिल है" ऑपरेटर, जो GIN अनुक्रमणिका का उपयोग कर सकता है। (json
. के लिए नहीं , केवल jsonb
!)
या आप अधिक विशिष्ट, गैर-डिफ़ॉल्ट GIN ऑपरेटर वर्ग jsonb_path_ops
का उपयोग करते हैं सूचकांक के लिए:
CREATE INDEX tracks_artists_gin_idx ON tracks
USING gin (artists jsonb_path_ops); -- !
वही क्वेरी।
वर्तमान में jsonb_path_ops
केवल @>
. का समर्थन करता है ऑपरेटर। लेकिन यह आमतौर पर बहुत छोटा और तेज़ होता है। अधिक अनुक्रमणिका विकल्प हैं, मैन्युअल में विवरण ।
यदि कॉलम artists
केवल उदाहरण में दिखाए गए नाम रखता है, यह केवल मानों . को संग्रहीत करने के लिए अधिक कुशल होगा JSON टेक्स्ट के रूप में आदिम और अनावश्यक कुंजी कॉलम नाम हो सकता है।
JSON ऑब्जेक्ट और आदिम प्रकारों के बीच अंतर पर ध्यान दें:
- PostgreSQL में json सरणी में अनुक्रमणिका का उपयोग करना
CREATE TABLE tracks (id serial, artistnames jsonb);
INSERT INTO tracks VALUES (2, '["The Dirty Heads", "Louis Richards"]');
CREATE INDEX tracks_artistnames_gin_idx ON tracks USING gin (artistnames);
प्रश्न:
SELECT * FROM tracks WHERE artistnames ? 'The Dirty Heads';
?
वस्तु के लिए काम नहीं करता मानों , बस कुंजी और सरणी तत्व ।
या:
CREATE INDEX tracks_artistnames_gin_idx ON tracks
USING gin (artistnames jsonb_path_ops);
प्रश्न:
SELECT * FROM tracks WHERE artistnames @> '"The Dirty Heads"'::jsonb;
यदि नाम अत्यधिक दोहराव वाले हों तो अधिक कुशल।
json
पोस्टग्रेज में 9.3+
यह एक IMMUTABLE
. के साथ काम करना चाहिए फ़ंक्शन :
CREATE OR REPLACE FUNCTION json2arr(_j json, _key text)
RETURNS text[] LANGUAGE sql IMMUTABLE AS
'SELECT ARRAY(SELECT elem->>_key FROM json_array_elements(_j) elem)';
यह कार्यात्मक अनुक्रमणिका बनाएं :
CREATE INDEX tracks_artists_gin_idx ON tracks
USING gin (json2arr(artists, 'name'));
और क्वेरी . का उपयोग करें इस तरह। WHERE
. में व्यंजक क्लॉज को इंडेक्स में से एक से मेल खाना चाहिए:
SELECT * FROM tracks
WHERE '{"The Dirty Heads"}'::text[] <@ (json2arr(artists, 'name'));
टिप्पणियों में प्रतिक्रिया के साथ अद्यतन किया गया। हमें सरणी ऑपरेटरों . का उपयोग करने की आवश्यकता है GIN अनुक्रमणिका का समर्थन करने के लिए।
"इसमें शामिल है" ऑपरेटर <@
इस मामले में।
फ़ंक्शन अस्थिरता पर नोट्स
आप अपना कार्य घोषित कर सकते हैं IMMUTABLE
भले ही json_array_elements()
<स्ट्राइक>नहीं हैस्ट्राइक> नहीं था।
अधिकांश JSON
फ़ंक्शन केवल STABLE
हुआ करते थे , नहीं IMMUTABLE
. इसे बदलने के लिए हैकर्स लिस्ट पर चर्चा हुई। अधिकांश IMMUTABLE
हैं अभी। इसके साथ जांचें:
SELECT p.proname, p.provolatile
FROM pg_proc p
JOIN pg_namespace n ON n.oid = p.pronamespace
WHERE n.nspname = 'pg_catalog'
AND p.proname ~~* '%json%';
कार्यात्मक अनुक्रमणिका केवल IMMUTABLE
के साथ काम करती हैं कार्य।