उस के लिए अस्वीकार्य मॉड्यूल का उपयोग करें - जो आप से लिंक कर रहे हैं उससे पूरी तरह से अलग है।
unaccent एक टेक्स्ट सर्च डिक्शनरी है, जो लेक्समेस से एक्सेंट (डियाक्रिटिक संकेतों) को हटाती है।
प्रति डेटाबेस एक बार स्थापित करें:
CREATE EXTENSION unaccent;
यदि आपको कोई त्रुटि मिलती है जैसे:
ERROR: could not open extension control file
"/usr/share/postgresql/<version>/extension/unaccent.control": No such file or directory
इस संबंधित उत्तर में दिए गए निर्देश की तरह अपने डेटाबेस सर्वर पर कंट्रिब पैकेज स्थापित करें:
अन्य बातों के अलावा, यह वह फ़ंक्शन प्रदान करता है जिसे unaccent()
आप अपने उदाहरण के साथ उपयोग कर सकते हैं (जहां LIKE
इसकी आवश्यकता नहीं है)।
SELECT *
FROM users
WHERE unaccent(name) = unaccent('João');
सूची
उस तरह के क्वेरी के लिए एक इंडेक्स का उपयोग करने के लिए, अभिव्यक्ति पर एक इंडेक्स बनाएं । हालाँकि , Postgres केवल IMMUTABLE
अनुक्रमणिका के कार्यों को स्वीकार करता है। यदि कोई फ़ंक्शन समान इनपुट के लिए एक अलग परिणाम दे सकता है, तो सूचकांक चुपचाप टूट सकता है।
unaccent()
केवल STABLE
नहींIMMUTABLE
दुर्भाग्य से, unaccent()
केवल है STABLE
, नहीं IMMUTABLE
। Pgsql- कीड़े पर इस धागे के अनुसार , यह तीन कारणों से है:
- यह एक शब्दकोश के व्यवहार पर निर्भर करता है।
- इस शब्दकोश का कोई हार्ड-वायर्ड कनेक्शन नहीं है।
- इसलिए यह वर्तमान पर भी निर्भर करता है
search_path
, जो आसानी से बदल सकता है।
वेब पर कुछ ट्यूटोरियल सिर्फ फंक्शन की अस्थिरता को बदलने का निर्देश देते हैं IMMUTABLE
। यह ब्रूट-फोर्स विधि कुछ शर्तों के तहत टूट सकती है।
दूसरों को एक सरल IMMUTABLE
आवरण समारोह का सुझाव दिया (जैसे मैंने अतीत में खुद किया था)।
इस बात पर बहस जारी है कि क्या दो मापदंडों के साथ वैरिएंट बनाया जाए IMMUTABLE
जो स्पष्ट रूप से इस्तेमाल किए गए शब्दकोश की घोषणा करता है। यहाँ या यहाँ पढ़ें ।
एक और विकल्प यह मॉड्यूल होगा जो म्यूथब्रेनज़ unaccent()
द्वारा IMMUTABLE फ़ंक्शन के साथ है, गितुब पर प्रदान किया गया है। खुद इसका परीक्षण नहीं किया। मुझे लगता है कि मैं एक बेहतर विचार के साथ आया हूं :
अभी के लिए सबसे अच्छा
यह दृष्टिकोण अन्य समाधानों के रूप में अधिक कुशल है, जो चारों ओर तैर रहा है, और सुरक्षित है । हार्ड-वायर्ड स्कीमा-योग्य फ़ंक्शन और डिक्शनरी के साथ दो-पैरामीटर फ़ॉर्म को निष्पादित करते हुए
एक IMMUTABLE
SQL आवरण फ़ंक्शन बनाएं ।
चूंकि एक गैर-अपरिवर्तनीय फ़ंक्शन नेस्टिंग किया है, इसलिए फ़ंक्शन इनलाइनिंग को अक्षम कर देगा, इसे C-फ़ंक्शन की एक प्रति के आधार पर, (नकली) भी घोषित IMMUTABLE
किया जाएगा। इसका एकमात्र उद्देश्य SQL फ़ंक्शन रैपर में उपयोग किया जाना है। इसका उपयोग अपने आप करने के लिए नहीं है।
परिष्कार की आवश्यकता है क्योंकि सी फ़ंक्शन की घोषणा में शब्दकोश को हार्ड-वायर करने का कोई तरीका नहीं है। (C कोड को स्वयं हैक करने की आवश्यकता होगी।) SQL आवरण फ़ंक्शन ऐसा करता है और फ़ंक्शन इनलाइनिंग और अभिव्यक्ति अनुक्रमित दोनों की अनुमति देता है ।
CREATE OR REPLACE FUNCTION public.immutable_unaccent(regdictionary, text)
RETURNS text LANGUAGE c IMMUTABLE PARALLEL SAFE STRICT AS
'$libdir/unaccent', 'unaccent_dict';
CREATE OR REPLACE FUNCTION public.f_unaccent(text)
RETURNS text LANGUAGE sql IMMUTABLE PARALLEL SAFE STRICT AS
$func$
SELECT public.immutable_unaccent(regdictionary 'public.unaccent', $1)
$func$;
PARALLEL SAFE
9.5 या उससे अधिक उम्र के दोनों कार्यों के लिए ड्रॉप ।
public
स्कीमा होना जहां आपने एक्सटेंशन स्थापित किया है ( public
डिफ़ॉल्ट है)।
स्पष्ट प्रकार की घोषणा ( regdictionary
) दुर्भावनापूर्ण उपयोगकर्ताओं द्वारा फ़ंक्शन के अतिभारित वेरिएंट के साथ काल्पनिक हमलों के खिलाफ बचाव करती है।
पहले, मैंने अस्वीकार्य मॉड्यूल के साथ भेजे गए STABLE
फ़ंक्शन के आधार पर एक आवरण समारोह की वकालत की unaccent()
। उस अक्षम फ़ंक्शन को इनलाइनिंग । यह संस्करण उस सरल आवरण समारोह की तुलना में दस गुना अधिक तेज़ी से निष्पादित होता है जो मैंने पहले यहां किया था।
और यह पहले से ही पहले संस्करण के रूप में दोगुना तेज़ था जो SET search_path = public, pg_temp
फ़ंक्शन में जोड़ा गया - जब तक मुझे पता नहीं चला कि शब्दकोश स्कीमा-योग्य हो सकता है, भी। अभी भी (पोस्टग्रेज 12) प्रलेखन से बहुत स्पष्ट नहीं है।
यदि आपको C फ़ंक्शन बनाने के लिए आवश्यक विशेषाधिकारों की कमी है, तो आप दूसरे सर्वोत्तम कार्यान्वयन पर वापस आते हैं : मॉड्यूल द्वारा प्रदान किए गए फ़ंक्शन के IMMUTABLE
आसपास एक फ़ंक्शन आवरण STABLE
unaccent()
:
CREATE OR REPLACE FUNCTION public.f_unaccent(text)
RETURNS text AS
$func$
SELECT public.unaccent('public.unaccent', $1) -- schema-qualify function and dictionary
$func$ LANGUAGE sql IMMUTABLE PARALLEL SAFE STRICT;
अंत में, प्रश्नों को तेज़ बनाने के लिए अभिव्यक्ति सूचकांक :
CREATE INDEX users_unaccent_name_idx ON users(public.f_unaccent(name));
फ़ंक्शन या शब्दकोश में किसी भी परिवर्तन के बाद इस फ़ंक्शन को शामिल करने वाले अनुक्रमणिकाओं को फिर से बनाना याद रखें , जैसे कि एक इन-प्लेस प्रमुख रिलीज़ अपग्रेड जो अनुक्रमणिका को फिर से नहीं बनाएगा। हाल की प्रमुख रिलीज में सभी unaccent
मॉड्यूल के लिए अपडेट थे ।
अनुक्रमणिका से मिलान करने के लिए क्वेरीज़ को समायोजित करें (ताकि क्वेरी योजनाकार इसका उपयोग करेगा):
SELECT * FROM users
WHERE f_unaccent(name) = f_unaccent('João');
आपको सही अभिव्यक्ति में फ़ंक्शन की आवश्यकता नहीं है। वहां आप 'Joao'
सीधे तरह से बिना तार के भी आपूर्ति कर सकते हैं।
तीव्र फ़ंक्शन अभिव्यक्ति इंडेक्स का उपयोग करके बहुत तेज़ प्रश्नों का अनुवाद नहीं करता है । यह पूर्व-संकलित मूल्यों पर काम करता है और पहले से ही बहुत तेज है। लेकिन अनुक्रमणिका लाभ का उपयोग नहीं करते हुए अनुरक्षण रखरखाव और क्वेरीज़।
क्लाइंट प्रोग्राम के लिए सुरक्षा पोस्टग्रेज 10.3 / 9.6.8 आदि के साथ कड़ी कर दी गई है। आपको किसी भी इंडेक्स में उपयोग किए जाने के दौरान स्कीमा-क्वालिफाइड फ़ंक्शन और डिक्शनरी नाम की आवश्यकता होती है। देख:
ligatures
Postgres में 9.5 या उससे अधिक 'ँ' या संयुक्ताक्षर 'ß' है मैन्युअल रूप से विस्तार किया जा करने के लिए (आपको लगता है कि जरूरत है), के बाद से unaccent()
हमेशा एक विकल्प एक पत्र:
SELECT unaccent('Œ Æ œ æ ß');
unaccent
----------
E A e a S
आप इस अपडेट को पोस्टग्रेस 9.6 में अस्वीकार्य पसंद करेंगे :
बढ़ाएँ contrib/unaccent
के मानक unaccent.rules
यूनिकोड के लिए जाना जाता सब डायाक्रिटिक्स को संभालने के लिए फ़ाइल, और सही ढंग से संयुक्ताक्षर का विस्तार (थॉमस मुनरो, लियोनार्ड बेनेडेट्टी)
बोल्ड जोर मेरा। अब हमें मिलता है:
SELECT unaccent('Œ Æ œ æ ß');
unaccent
----------
OE AE oe ae ss
पैटर्न मिलान
के लिए LIKE
या ILIKE
मनमाने ढंग से पैटर्न के साथ, pg_trgm
PostgreSQL 9.1 या बाद में मॉड्यूल के साथ गठबंधन करें । एक ट्रिम GIN (आमतौर पर बेहतर) या GIST अभिव्यक्ति सूचकांक बनाएं। GIN के लिए उदाहरण:
CREATE INDEX users_unaccent_name_trgm_idx ON users
USING gin (f_unaccent(name) gin_trgm_ops);
जैसे प्रश्नों के लिए इस्तेमाल किया जा सकता है:
SELECT * FROM users
WHERE f_unaccent(name) LIKE ('%' || f_unaccent('João') || '%');
सादे बीटी से बनाए रखने के लिए GIN और GIST इंडेक्स अधिक महंगे हैं:
बस बाएं-एंकर पैटर्न के लिए सरल समाधान हैं। पैटर्न मिलान और प्रदर्शन के बारे में अधिक जानकारी:
pg_trgm
"समानता" ( %
) और "दूरी" ( <->
) के लिए उपयोगी ऑपरेटर भी प्रदान करता है ।
ट्राइग्राम इंडेक्स, ~
एट अल के साथ सरल नियमित अभिव्यक्तियों का भी समर्थन करता है । और मामले असंवेदनशील पैटर्न के साथ मिलान ILIKE
: