2009-12-14 10 views
5

मेरे पास ऐसी साइट है जिसे लगभग 20-30k रिकॉर्ड के माध्यम से खोजना होगा, जो ज्यादातर फिल्म और टीवी शो नाम हैं। साइट memcache के साथ php/mysql चलाती है।क्या सबसे आसान साइट खोज एप्लिकेशन लागू करने के लिए है, जो अस्पष्ट खोज का समर्थन करता है?

मैं soundex() के साथ FULLTEXT को प्रतिस्थापित करने के लिए देख रहा हूं, जो कि वर्तमान में है, जो काम करता है ... किस प्रकार की है, लेकिन कई परिस्थितियों में बहुत अच्छा नहीं है।

क्या वहां कोई सभ्य खोज स्क्रिप्ट है जो कार्यान्वित करने के लिए सरल है, और एक सभ्य खोज क्षमता (तालिका में 3 कॉलम) प्रदान करेगी।

उत्तर

6

ewemli के जवाब सही दिशा में है, लेकिन आपको पूर्ण पाठ को प्रतिस्थापित नहीं करने के लिए FULLTEXT और साउंडएक्स मैपिंग का संयोजन होना चाहिए, अन्यथा आपकी पसंद की क्वेरी बहुत धीमी हो सकती है।

create table with_soundex (
    id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, 
    original TEXT, 
    soundex TEXT, 
    FULLTEXT (soundex) 
); 

insert into with_soundex (original, soundex) values 

('add some test cases', CONCAT_WS(' ', soundex('add'), soundex('some'), soundex('test'), soundex('cases'))), 
('this is some text', CONCAT_WS(' ', soundex('this'), soundex('is'), soundex('some'), soundex('text'))), 
('one more test case', CONCAT_WS(' ', soundex('one'), soundex('more'), soundex('test'), soundex('case'))), 
('just filling the index', CONCAT_WS(' ', soundex('just'), soundex('filling'), soundex('the'), soundex('index'))), 
('need one more example', CONCAT_WS(' ', soundex('need'), soundex('one'), soundex('more'), soundex('example'))), 
('seems to need more', CONCAT_WS(' ', soundex('seems'), soundex('to'), soundex('need'), soundex('more'))) 
('some helpful cases to consider', CONCAT_WS(' ', soundex('some'), soundex('helpful'), soundex('cases'), soundex('to'), soundex('consider'))) 

select * from with_soundex where match(soundex) against (soundex('test')); 
+----+---------------------+---------------------+ 
| id | original   | soundex    | 
+----+---------------------+---------------------+ 
| 1 | add some test cases | A300 S500 T230 C000 | 
| 2 | this is some text | T200 I200 S500 T230 | 
| 3 | one more test case | O500 M600 T230 C000 | 
+----+---------------------+---------------------+ 

select * from with_soundex where match(soundex) against (CONCAT_WS(' ', soundex('test'), soundex('some'))); 
+----+--------------------------------+---------------------------+ 
| id | original      | soundex     | 
+----+--------------------------------+---------------------------+ 
| 1 | add some test cases   | A300 S500 T230 C000  | 
| 2 | this is some text    | T200 I200 S500 T230  | 
| 3 | one more test case    | O500 M600 T230 C000  | 
| 7 | some helpful cases to consider | S500 H414 C000 T000 C5236 | 
+----+--------------------------------+---------------------------+ 

काफ़ी अच्छा परिणाम देता है (soundex algo की सीमाओं के भीतर) यही कारण है कि, जबकि एक सूचकांक की अधिकतम लाभ लेने (किसी भी प्रश्न की तरह '% foo' तालिका में प्रत्येक पंक्ति स्कैन करने के लिए है)।

प्रत्येक शब्द पर ध्वनि चलाने के महत्व को ध्यान दें, पूरे वाक्यांश पर नहीं। आप एसक्यूएल करने के बजाय प्रत्येक शब्द पर ध्वनि का अपना संस्करण भी चला सकते हैं लेकिन उस स्थिति में सुनिश्चित करें कि एल्गोरिदम के बीच अंतर होने पर आप इसे संग्रहीत और पुनर्प्राप्त करते समय दोनों करते हैं (उदाहरण के लिए, MySQL का अहंकार सीमित नहीं है खुद को मानक 4 chars)

0

mysql में एक समारोह SOUNDEX है। यदि आप एक फिल्म का शीर्षक के लिए खोज करना चाहते हैं:

select * from movie where soundex(title) = soundex('the title'); 

बेशक यह इस तरह फिल्म या भूखंड सारांश के रूप में, पाठ में खोज करने के लिए काम नहीं करता।


Soundex एक अपेक्षाकृत सरल algo है। तुम भी अनुप्रयोगी स्तर पर सभी कि संभाल करने के लिए तय कर सकते हैं, यह आसान हो सकता है:

  • जब पाठ संग्रहीत किया जाता है, यह tokenize और दो में मूल पाठ और soundex संस्करण सभी शब्दों पर soundex लागू
  • दुकान कॉलम
  • जब आप खोज करते हैं, तो ऐप पर ध्वनि का गणना करें। स्तर और फिर डीबी स्तर पर एक नियमित LIKE का उपयोग करें।
+0

मैं चिंतित हूं। अगर film.title "एपोकैलीप्स नाउ" है लेकिन उपयोगकर्ता "एपोकैलीप्स गाय" खोजता है, तो साउंडएक्स को एक मैच मिल सकता है '... जहां film.title = "$ user_title" या soundex (film.title) = soundex ($ user_title) '; लेकिन यह कहने में काम नहीं करेगा, film.intro var (255) जिसमें "मार्टिन शीन" शामिल है और उपयोगकर्ता ने "मार्टिन शीन" की खोज की है? क्षमा करें अगर यह क्यू/टिप्पणी गलत जगह पर है, तो कृपया मुझे सही बताएं। – Cups

+0

साउंडएक्स ('मार्टिन शीन के साथ एक फिल्म') -> ए513563525, ध्वनि का चयन करें ('ए'), साउंडएक्स ('मूवी'), साउंडएक्स ('साथ'), साउंडएक्स ('मार्टिन'), साउंडएक्स ('शीन'); -> ए000, एम 100, डब्ल्यू 300, एम 635, एस 500 तो यदि आप टेक्स्ट 'ए000 एम 100 डब्ल्यू 300 एम 635 एस 500' के साउंडएक्स संस्करण को स्टोर करते हैं और LIKE '% M635% S500%' के साथ खोज करते हैं तो यह ठीक हो सकता है। हालांकि यह अभी भी इष्टतम नहीं है। 'मार्ट इंजेन' (नाम की संभावित गलतफहमी) के लिए खोज करना "% M630% I525%" की तरह उपज और काम नहीं करेगा। – ewernli

1

आप देख रहे हैं एक सरल मौजूदा समाधान के लिए के बजाय बनाने यदि अपने स्वयं के समाधान की जाँच

0

ध्वनि के पास अस्पष्ट खोज से निपटने के लिए सीमाएं हैं। एक बेहतर कार्य संपादन दूरी है, जिसे यूडीएफ का उपयोग करके MySQL में एकीकृत किया जा सकता है। लिनक्स पर MySQL के लिए C++ कार्यान्वयन के लिए http://flamingo.ics.uci.edu/toolkit/ देखें।

संबंधित मुद्दे