आपके एप्लिकेशन में खोज जोड़ने से अक्सर डेवलपर्स इलास्टिक्स खोज तक पहुंच जाते हैं – लेकिन PostgreSQL में शक्तिशाली अंतर्निहित पूर्ण-पाठ खोज है जो अतिरिक्त बुनियादी ढांचे के बिना अधिकांश जरूरतों को पूरा करती है। यह मार्गदर्शिका दिखाती है कि बुनियादी बातों से लेकर रैंकिंग और हाइलाइटिंग तक, PostgreSQL के साथ उत्पादन खोज कैसे बनाई जाए।
📋 Table of Contents
- खोज के लिए PostgreSQL का उपयोग क्यों करें?
- tsvector और tsquery को समझना
- बुनियादी पूर्ण-पाठ खोज
- इंडेक्स
- प्रासंगिकता के आधार पर रैंकिंग परिणाम
- मेल खाने वाले शब्दों को हाइलाइट करना
- Node.js से इसका उपयोग करना
- फ़ज़ी/टाइपो-सहिष्णु खोज जोड़ना
- इसके बजाय इलास्टिक्स खोज का उपयोग कब करें
- अक्सर पूछे जाने वाले प्रश्न
- निष्कर्ष
खोज के लिए PostgreSQL का उपयोग क्यों करें?
- कोई अतिरिक्त बुनियादी ढांचा नहीं: अपने मौजूदा डेटाबेस का उपयोग करें – चलाने और सिंक करने के लिए कोई अलग खोज इंजन नहीं
- अधिकांश ऐप्स के लिए पर्याप्त अच्छा: उचित अनुक्रमण के साथ लाखों दस्तावेज़ों को संभालता है
- लेन-देन संबंधी स्थिरता: अपने डेटा के साथ इंडेक्स अपडेट खोजें, कोई सिंक लैग नहीं
- समृद्ध विशेषताएं: रैंकिंग, स्टेमिंग, हाइलाइटिंग, कई भाषाओं का निर्माण
tsvector और tsquery को समझना
-- tsvector: a processed, searchable representation of text
-- tsquery: a search query
SELECT to_tsvector('english', 'The quick brown foxes are jumping');
-- 'brown':3 'fox':4 'jump':6 'quick':2
-- Note: stemming (foxes->fox, jumping->jump) and stopword removal (the, are)
SELECT to_tsvector('english', 'The quick brown foxes')
@@ to_tsquery('english', 'fox');
-- true - matches because 'foxes' stems to 'fox'
बुनियादी पूर्ण-पाठ खोज
-- Search articles by title and content
SELECT id, title
FROM articles
WHERE to_tsvector('english', title || ' ' || content)
@@ to_tsquery('english', 'postgresql & search');
-- & means AND, | means OR, ! means NOT
-- plainto_tsquery handles user input safely (treats as AND)
SELECT id, title
FROM articles
WHERE to_tsvector('english', title || ' ' || content)
@@ plainto_tsquery('english', 'postgresql search tutorial');
-- websearch_to_tsquery supports Google-like syntax (quotes, OR, -)
SELECT id, title
FROM articles
WHERE to_tsvector('english', content)
@@ websearch_to_tsquery('english', '"full text" search -elasticsearch');
इंडेक्स
के साथ एक प्रीकंप्यूटेड टीएसवेक्टर कॉलम जोड़ना प्रत्येक क्वेरी पर tsvector की गणना धीमी है। इसे GIN इंडेक्स वाले कॉलम में स्टोर करें:
-- Add a generated tsvector column (auto-updates with the data)
ALTER TABLE articles ADD COLUMN search_vector tsvector
GENERATED ALWAYS AS (
to_tsvector('english', coalesce(title, '') || ' ' || coalesce(content, ''))
) STORED;
-- Create a GIN index for fast searching
CREATE INDEX articles_search_idx ON articles USING GIN (search_vector);
-- Now searches are fast and use the index
SELECT id, title FROM articles
WHERE search_vector @@ plainto_tsquery('english', 'postgresql search');
प्रासंगिकता के आधार पर रैंकिंग परिणाम
-- ts_rank scores how well each row matches
SELECT id, title,
ts_rank(search_vector, query) AS rank
FROM articles, plainto_tsquery('english', 'postgresql search') query
WHERE search_vector @@ query
ORDER BY rank DESC
LIMIT 20;
-- Weight title matches higher than content
ALTER TABLE articles ADD COLUMN search_vector tsvector
GENERATED ALWAYS AS (
setweight(to_tsvector('english', coalesce(title, '')), 'A') ||
setweight(to_tsvector('english', coalesce(content, '')), 'B')
) STORED;
-- 'A' weight (title) ranks higher than 'B' weight (content)
मेल खाने वाले शब्दों को हाइलाइट करना
-- ts_headline returns snippets with matched terms highlighted
SELECT id, title,
ts_headline('english', content, query,
'StartSel=, StopSel=, MaxWords=35, MinWords=15') AS snippet
FROM articles, plainto_tsquery('english', 'postgresql') query
WHERE search_vector @@ query
ORDER BY ts_rank(search_vector, query) DESC;
-- snippet contains the relevant excerpt with around matches
Node.js से इसका उपयोग करना
app.get('/search', async (req, res) => {
const q = req.query.q;
if (!q) return res.json({ results: [] });
const result = await db.query(`
SELECT id, title,
ts_headline('english', content, query,
'StartSel=,StopSel=,MaxWords=35') AS snippet,
ts_rank(search_vector, query) AS rank
FROM articles, plainto_tsquery('english', $1) query
WHERE search_vector @@ query
ORDER BY rank DESC
LIMIT 20
`, [q]);
res.json({ results: result.rows });
});
फ़ज़ी/टाइपो-सहिष्णु खोज जोड़ना
-- Enable the pg_trgm extension for fuzzy matching (handles typos)
CREATE EXTENSION IF NOT EXISTS pg_trgm;
-- Trigram index for similarity search
CREATE INDEX articles_title_trgm ON articles USING GIN (title gin_trgm_ops);
-- Find titles similar to a (possibly misspelled) query
SELECT title, similarity(title, 'postgres serch') AS sim
FROM articles
WHERE title % 'postgres serch' -- % is the similarity operator
ORDER BY sim DESC;
-- Matches 'PostgreSQL search' despite the typo
इसके बजाय इलास्टिक्स खोज का उपयोग कब करें
PostgreSQL पूर्ण-पाठ खोज अधिकांश अनुप्रयोगों को अच्छी तरह से संभालती है। जब आपको आवश्यकता हो तो इलास्टिक्स खोज पर विचार करें:
- जटिल प्रासंगिकता ट्यूनिंग के साथ बहुत बड़े पैमाने पर (सैकड़ों लाखों दस्तावेज़)
- उन्नत सुविधाएँ: पहलूबद्ध खोज, जटिल एकत्रीकरण, बड़े पैमाने पर भू-खोज
- अपने डेटाबेस से परे कई डेटा स्रोतों में खोजें
- खोज डेटा पर वास्तविक समय विश्लेषण
अधिकांश ऐप्स के लिए – ब्लॉग, ई-कॉमर्स, सामग्री साइटें, SaaS – PostgreSQL खोज सरल है, किसी अतिरिक्त बुनियादी ढांचे की आवश्यकता नहीं है, और पर्याप्त से अधिक है।
अक्सर पूछे जाने वाले प्रश्न
प्रश्न: क्या PostgreSQL खोज काफी अच्छी है, या क्या मुझे Elasticsearch की आवश्यकता है?
उत्तर: अधिकांश अनुप्रयोगों के लिए, PostgreSQL पूर्ण-पाठ खोज पर्याप्त से अधिक है – यह रैंकिंग, हाइलाइटिंग और स्टेमिंग के साथ लाखों दस्तावेज़ों को संभालती है। Elasticsearch का उपयोग केवल बहुत बड़े पैमाने पर, उन्नत पहलू वाली खोज, या कई डेटा स्रोतों में खोज के लिए करें। इलास्टिक्स खोज अवसंरचना को समय से पहले न जोड़ें।
प्रश्न: मैं खोज में टाइपो त्रुटियों को कैसे संभालूं?
उ: ट्रिग्राम समानता मिलान के लिए pg_trgm एक्सटेंशन का उपयोग करें, जो टाइपो और गलत वर्तनी को सहन करता है। इसे पूर्ण-पाठ खोज के साथ संयोजित करें – मुख्य खोज के लिए tsvector का उपयोग करें और फ़ॉलबैक के रूप में या स्वत: पूर्ण/सुझावों के लिए ट्रिग्राम समानता का उपयोग करें।
प्रश्न: मेरी पूर्ण-पाठ खोज धीमी क्यों है?
उ: आप शायद बिना इंडेक्स के हर क्वेरी पर to_tsvector की गणना कर रहे हैं। GIN इंडेक्स के साथ एक संग्रहीत जेनरेटेड tsvector कॉलम जोड़ें। यह खोजने योग्य प्रतिनिधित्व की पूर्व-गणना करता है और बड़ी तालिकाओं पर भी खोज को तेज़ बनाता है।
प्रश्न:plainto_tsquery बनाम to_tsquery बनाम websearch_to_tsquery?
A: to_tsquery ऑपरेटर सिंटैक्स (&, |) की आवश्यकता है – प्रोग्रामेटिक प्रश्नों के लिए अच्छा है। plainto_tsquery सादे उपयोगकर्ता इनपुट को संभालता है (शब्दों को AND के रूप में मानता है) – उपयोगकर्ता खोज बॉक्स के लिए सुरक्षित। websearch_to_tsquery Google-जैसे सिंटैक्स (उद्धरण, OR, -) का समर्थन करता है – उपयोगकर्ता-सामना वाली खोज के लिए सर्वोत्तम।
प्रश्न: क्या मैं अनेक भाषाओं में खोज सकता हूँ?
उत्तर: हाँ – PostgreSQL में कई भाषाओं (अंग्रेजी, स्पेनिश, फ़्रेंच, आदि) के लिए टेक्स्ट खोज कॉन्फ़िगरेशन हैं जो प्रति भाषा स्टेमिंग और स्टॉपवर्ड को संभालते हैं। भाषा को to_tsvector/to_tsquery में निर्दिष्ट करें। यदि आपकी सामग्री बहुभाषी है तो एक भाषा कॉलम संग्रहीत करें।
निष्कर्ष
PostgreSQL की अंतर्निहित पूर्ण-पाठ खोज एक अलग खोज इंजन की जटिलता के बिना अधिकांश अनुप्रयोगों की खोज आवश्यकताओं को संभालती है।का प्रयोग करें प्रदर्शन के लिए GIN इंडेक्स के साथ संग्रहीत जेनरेटेड tsvector कॉलम, प्रासंगिकता रैंकिंग के लिए ts_rank, हाइलाइटिंग के लिए ts_headline, और टाइपो टॉलरेंस के लिए pg_trgm. महत्वपूर्ण फ़ील्ड (जैसे शीर्षक) को सेटवेट के साथ अधिक महत्व दें, और सुरक्षित उपयोगकर्ता इनपुट के लिएplainto_tsquery या websearch_to_tsquery का उपयोग करें। बहुत बड़े पैमाने पर या उन्नत पहलू वाली खोज के लिए इलास्टिक्स खोज को आरक्षित करें। ब्लॉग, ई-कॉमर्स, सामग्री साइटों और अधिकांश SaaS ऐप्स के लिए, PostgreSQL खोज सरल है, इसके लिए किसी अतिरिक्त बुनियादी ढांचे की आवश्यकता नहीं है, यह आपके डेटा के अनुरूप रहता है, और उत्कृष्ट प्रदर्शन करता है – समर्पित खोज बुनियादी ढांचे तक पहुंचने से पहले एक बढ़िया डिफ़ॉल्ट विकल्प।
🔗 Share this article
✍️ Leave a Comment