यदि आप मनमाना सबस्ट्रिंग मिलानों को अनुकूलित करना चाहते हैं, तो एक विकल्प <कोड का उपयोग करना है।>pg_tgrm मॉड्यूल . एक अनुक्रमणिका जोड़ें:
CREATE INDEX table_location_name_trigrams_key ON table
USING gin (location_name gin_trgm_ops);
यह "सिंपल कैफे" को "सिम", "आईपी", "एमपीएल", आदि में तोड़ देगा, और प्रत्येक पंक्ति में प्रत्येक ट्रिगम के लिए इंडेक्स में एक प्रविष्टि जोड़ देगा। फिर क्वेरी प्लानर स्वचालित रूप से इस इंडेक्स का उपयोग सबस्ट्रिंग पैटर्न मिलान के लिए कर सकता है, जिसमें शामिल हैं:
SELECT * FROM table WHERE location_name ILIKE '%cafe%';
यह क्वेरी इंडेक्स में "caf" और "afe" को खोजेगी, चौराहे को ढूंढेगी, उन पंक्तियों को प्राप्त करेगी, फिर प्रत्येक पंक्ति को अपने पैटर्न के विरुद्ध जांचें। (वह अंतिम जांच आवश्यक है क्योंकि "कैफ़" और "एफ़ई" का प्रतिच्छेदन "साधारण कैफ़े" और "असुरक्षित मचान" दोनों से मेल खाता है, जबकि "% कैफ़े%" केवल एक से मेल खाना चाहिए)। इंडेक्स अधिक प्रभावी हो जाता है क्योंकि इनपुट पैटर्न लंबा हो जाता है क्योंकि यह अधिक पंक्तियों को बाहर कर सकता है, लेकिन यह अभी भी पूरे शब्दों को अनुक्रमित करने के रूप में कुशल नहीं है, इसलिए to_tsvector
पर प्रदर्शन में सुधार की उम्मीद न करें। ।
पकड़ यह है कि, तीन वर्णों के नीचे के पैटर्न के लिए ट्रिगर बिल्कुल भी काम नहीं करते हैं। यह आपके आवेदन के लिए डील-ब्रेकर हो भी सकता है और नहीं भी।
संपादित करें: मैंने शुरुआत में इसे एक टिप्पणी के रूप में जोड़ा था।
कल रात मुझे एक और विचार आया जब मैं ज्यादातर सो रहा था। एक cjk_chars
बनाएं फ़ंक्शन जो एक इनपुट स्ट्रिंग लेता है, regexp_matches
संपूर्ण CJK यूनिकोड पर्वतमाला, और ऐसे किसी भी वर्ण या NULL
. की एक सरणी देता है अगर कोई नहीं cjk_chars(location_name)
. पर GIN इंडेक्स जोड़ें . फिर इसके लिए क्वेरी करें:
WHERE CASE
WHEN cjk_chars('query') IS NOT NULL THEN
cjk_chars(location_name) @> cjk_chars('query')
AND location_name LIKE '%query%'
ELSE
<tsvector/trigrams>
END
टा-दा, यूनिग्राम!