2011-05-27 13 views
6

के साथ एक उपसर्ग में समाप्त होने वाले वाक्यांश से मेल खाता है। मैं PostgreSQL में एक tsvector का उपयोग कर SELECT * FROM table WHERE attr LIKE '%text%' जैसे कुछ अनुकरण करने का एक तरीका ढूंढ रहा हूं।पूर्ण पाठ खोज

मैंने एक शब्दकोश का उपयोग किए बिना एक tsvector विशेषता बनाई है। अब, एक प्रश्न की तरह ...

SELECT title 
FROM table 
WHERE title_tsv @@ plainto_tsquery('ph:*'); 

... 'भौतिकी', 'पीएचपी' आदि जैसे सभी शीर्षक वापसी होगी लेकिन मैं एक प्रश्न है कि सभी रिकॉर्ड रिटर्न जहां शीर्षक के साथ शुरू कैसे बना सकते हैं ' ज़ेंड फ्रैम '(उदाहरण के लिए' ज़ेंड फ्रेमवर्क ') वापस आना चाहिए?

SELECT title 
FROM table 
WHERE title_tsv @@ to_tsquery('zend') 
AND title_tsv @@ to_tsquery('fram:*'); 

बहरहाल, यह थोड़ा अजीब लगता है:

बेशक

, मैं की तरह कुछ इस्तेमाल कर सकते हैं।

तो, सवाल यह है: वहाँ क्वेरी की तरह कुछ का उपयोग कर ऊपर दिए गए तैयार करने के लिए एक तरीका है:

SELECT title 
FROM table 
WHERE title_tsv @@ to_tsquery('zend & fram:*') 

लेकिन निश्चित है कि पाता है:

SELECT title 
FROM table 
WHERE title_tsv @@ to_tsquery('zend fram:*'); 

उत्तर

5
SELECT title 
FROM table 
WHERE title_tsv @@ to_tsquery('zend') and 
title_tsv @@ to_tsquery('fram:*') 

के बराबर है "ज़ेंड के पास कोई ढांचा नहीं है"।

आप निश्चित रूप से स्क्वायर मैच के बाद शीर्षक के खिलाफ एक नियमित अभिव्यक्ति मैच व्यक्त कर सकते हैं, लेकिन आपको यह सुनिश्चित करने के लिए व्याख्या का उपयोग करना होगा कि पहले की बजाय tsquery के बाद निष्पादित किया जा रहा था।

2

trigrams और जिन/गिस्ट इंडेक्स का उपयोग करके पोस्टग्रेज़ में ऐसा करने का एक तरीका है। एक साधारण उदाहरण है, लेकिन क्रिस्टो कैव द्वारा इस आलेख में कुछ मोटे किनारों के साथ: Substring Search

1

नहीं एक सुंदर समाधान है, लेकिन यह काम करना चाहिए:

psql=# SELECT regexp_replace(cast(plainto_tsquery('Zend Fram') as text), E'(\'\\w+\')', E'\\1:*', 'g') ; 
    regexp_replace  
--------------------- 
'zend':* & 'fram':* 
(1 row) 

यह की तरह इस्तेमाल किया जा सकता है:

psql=# SELECT title FROM table WHERE title_tsv(title) @@ to_tsquery(regexp_replace(cast(plainto_tsquery('Zend Fram') as text), E'(\'\\w+\')', E'\\1:*', 'g')); 

यह कैसे काम करता है:

  1. सादा tsquery डाले एक स्ट्रिंग के लिए: cast(plainto_tsquery('Zend Fram') as text)
  2. को जोड़ने के लिए रेगेक्स का उपयोग करता है प्रत्येक खोज शब्द के लिएउपसर्ग मैचर: regexp_replace(..., E'(\'\\w+\')', E'\\1:*', 'g')
  3. इसे वापस एक गैर-सादा tsquery में परिवर्तित करता है। to_tsquery(...)
  4. और खोज अभिव्यक्ति SELECT title FROM table WHERE title_tsv(title) @@ ...
2

Postgres 9.6 का परिचय पूर्ण पाठ खोज के लिए वाक्यांश खोज क्षमताओं में इसे इस्तेमाल करता है।तो यह अब काम करता है:

SELECT title 
FROM tbl 
WHERE title_tsv @@ to_tsquery('zend <-> fram:*');

<-> being the FOLLOWED BY operator.

यह 'foo Zend फ्रेमवर्क बार' या 'Zend फ्रेम', लेकिन नहीं 'foo Zend कोई ढांचा बार है' पाता है।

release notes for Postgres 9.6:

एक वाक्यांश-खोज प्रश्न का हवाला देते हुए नई ऑपरेटरों <-> और <N> का उपयोग कर tsquery इनपुट में निर्दिष्ट किया जा सकता है। पूर्व का मतलब है कि उस क्रम में एक-दूसरे के समीप दिखाई देने के बाद पहले और लेक्सम लेते हैं। उत्तरार्द्ध का अर्थ है कि वे वास्तव में N lexemes अलग होना चाहिए।

सर्वश्रेष्ठ प्रदर्शन के समर्थन के लिए एक जिन सूचकांक के साथ क्वेरी:

CREATE INDEX tbl_title_tsv_idx ON tbl USING GIN (title_tsv); 

या सभी (यह सूजन और उलझी राईट) पर तालिका में title_tsv की दुकान नहीं है। आप एक अभिव्यक्ति सूचकांक के बजाय का उपयोग कर सकते हैं:

CREATE INDEX tbl_title_tsv_idx ON tbl USING GIN (to_tsvector('english', title)); 

आप पाठ खोज विन्यास (अक्सर भाषा-विशिष्ट) अभिव्यक्ति अपरिवर्तनीय बनाने के लिए निर्दिष्ट करने के लिए की जरूरत है। और तदनुसार क्वेरी को अनुकूलित करें:

... 
WHERE to_tsvector('english', title) @@ to_tsquery('english', 'zend <-> fram:*'); 
संबंधित मुद्दे