Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

समान परिणाम कैसे खोजें और समानता के आधार पर छाँटें?

मैंने पाया है कि लेवेनशेटिन दूरी अच्छी हो सकती है जब आप किसी अन्य पूर्ण स्ट्रिंग के विरुद्ध पूर्ण स्ट्रिंग खोज रहे हों, लेकिन जब आप स्ट्रिंग के भीतर कीवर्ड ढूंढ रहे हों, तो यह विधि वांछित परिणाम (कभी-कभी) वापस नहीं आती है। इसके अलावा, SOUNDEX फ़ंक्शन अंग्रेजी के अलावा अन्य भाषाओं के लिए उपयुक्त नहीं है, इसलिए यह काफी सीमित है। आप LIKE से दूर हो सकते हैं, लेकिन यह वास्तव में बुनियादी खोजों के लिए है। आप जो हासिल करना चाहते हैं, उसके लिए आप अन्य खोज विधियों पर गौर करना चाह सकते हैं। उदाहरण के लिए:

आप Lucene का उपयोग कर सकते हैं आपकी परियोजनाओं के लिए खोज आधार के रूप में। यह अधिकांश प्रमुख प्रोग्रामिंग भाषाओं में लागू किया गया है और यह काफी तेज और बहुमुखी होगा। यह विधि शायद सबसे अच्छी है, क्योंकि यह न केवल सबस्ट्रिंग की खोज करती है, बल्कि अक्षर ट्रांसपोजिशन, उपसर्ग और प्रत्यय (सभी संयुक्त) भी खोजती है। हालांकि, आपको एक अलग अनुक्रमणिका रखने की आवश्यकता है (हालांकि कभी-कभी एक स्वतंत्र स्क्रिप्ट से इसे अपडेट करने के लिए CRON का उपयोग करना काम करता है)।

या, यदि आप एक MySQL समाधान चाहते हैं, तो पूर्ण टेक्स्ट कार्यक्षमता बहुत अच्छी है, और निश्चित रूप से संग्रहीत प्रक्रिया से तेज़ है। यदि आपकी टेबल MyISAM नहीं हैं, तो आप एक अस्थायी टेबल बना सकते हैं, फिर अपनी पूर्ण टेक्स्ट खोज कर सकते हैं:

CREATE TABLE IF NOT EXISTS `tests`.`data_table` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(2000) CHARACTER SET latin1 NOT NULL,
  `description` text CHARACTER SET latin1 NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1 ;

डेटा जेनरेटर का उपयोग करें कुछ यादृच्छिक डेटा उत्पन्न करने के लिए यदि आप इसे स्वयं बनाने से परेशान नहीं होना चाहते हैं...

** नोट ** :कॉलम का प्रकार latin1_bin . होना चाहिए latin1 . के साथ असंवेदनशील केस के बजाय केस सेंसिटिव सर्च करने के लिए . यूनिकोड स्ट्रिंग्स के लिए, मैं utf8_bin का सुझाव दूंगा केस सेंसिटिव और utf8_general_ci . के लिए केस असंवेदनशील खोजों के लिए।

DROP TABLE IF EXISTS `tests`.`data_table_temp`;
CREATE TEMPORARY TABLE `tests`.`data_table_temp`
   SELECT * FROM `tests`.`data_table`;

ALTER TABLE `tests`.`data_table_temp`  ENGINE = MYISAM;

ALTER TABLE `tests`.`data_table_temp` ADD FULLTEXT `FTK_title_description` (
  `title` ,
  `description`
);

SELECT *,
       MATCH (`title`,`description`)
       AGAINST ('+so* +nullam lorem' IN BOOLEAN MODE) as `score`
  FROM `tests`.`data_table_temp`
 WHERE MATCH (`title`,`description`)
       AGAINST ('+so* +nullam lorem' IN BOOLEAN MODE)
 ORDER BY `score` DESC;

DROP TABLE `tests`.`data_table_temp`;

इसके बारे में MySQL API रेफरेंस पेज

इसका नकारात्मक पक्ष यह है कि यह अक्षर ट्रांसपोज़िशन या "समान, लगता है" शब्दों की तलाश नहीं करेगा।

** अपडेट करें **

अपनी खोज के लिए ल्यूसीन का उपयोग करते हुए, आपको बस एक क्रॉन जॉब बनाने की आवश्यकता होगी (सभी वेब होस्ट्स में यह "फीचर" होता है) जहां यह जॉब केवल एक PHP स्क्रिप्ट को निष्पादित करेगा (जैसे "cd /path/to/script; php searchindexer.php" ) जो इंडेक्स को अपडेट करेगा। इसका कारण यह है कि हजारों "दस्तावेज़ों" (पंक्तियों, डेटा, आदि) को अनुक्रमित करने में कई सेकंड, यहां तक ​​कि मिनट भी लग सकते हैं, लेकिन यह सुनिश्चित करना है कि सभी खोजें जितनी जल्दी हो सके निष्पादित की जाती हैं। इसलिए, आप सर्वर द्वारा चलाए जाने के लिए विलंब कार्य बनाना चाह सकते हैं। यह रात भर हो सकता है, या अगले घंटे में, यह आप पर निर्भर है। PHP स्क्रिप्ट कुछ इस तरह दिखनी चाहिए:

$indexer = Zend_Search_Lucene::create('/path/to/lucene/data');

Zend_Search_Lucene_Analysis_Analyzer::setDefault(
  // change this option for your need
  new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive()
);

$rowSet = getDataRowSet();  // perform your SQL query to fetch whatever you need to index
foreach ($rowSet as $row) {
   $doc = new Zend_Search_Lucene_Document();
   $doc->addField(Zend_Search_Lucene_Field::text('field1', $row->field1, 'utf-8'))
       ->addField(Zend_Search_Lucene_Field::text('field2', $row->field2, 'utf-8'))
       ->addField(Zend_Search_Lucene_Field::unIndexed('someValue', $someVariable))
       ->addField(Zend_Search_Lucene_Field::unIndexed('someObj', serialize($obj), 'utf-8'))
  ;
  $indexer->addDocument($doc);
}

// ... you can get as many $rowSet as you want and create as many documents
// as you wish... each document doesn't necessarily need the same fields...
// Lucene is pretty flexible on this

$indexer->optimize();  // do this every time you add more data to you indexer...
$indexer->commit();    // finalize the process

फिर, यह मूल रूप से आप कैसे खोजते हैं (मूल खोज):

$index = Zend_Search_Lucene::open('/path/to/lucene/data');

// same search options
Zend_Search_Lucene_Analysis_Analyzer::setDefault(
   new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive()
);

Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding('utf-8');

$query = 'php +field1:foo';  // search for the word 'php' in any field,
                                 // +search for 'foo' in field 'field1'

$hits = $index->find($query);

$numHits = count($hits);
foreach ($hits as $hit) {
   $score = $hit->score;  // the hit weight
   $field1 = $hit->field1;
   // etc.
}

Java में ल्यूसीन के बारे में बेहतरीन साइटें यहां दी गई हैं , PHP , और .Net

निष्कर्ष में प्रत्येक खोज विधियों के अपने फायदे और नुकसान होते हैं:

  • आपने Sphinx search का उल्लेख किया है और यह बहुत अच्छा लगता है, जब तक आप अपने वेब होस्ट पर डीमॉन को चला सकते हैं।
  • Zend Lucene को डेटाबेस को फिर से इंडेक्स करने के लिए क्रॉन जॉब की आवश्यकता होती है। हालांकि यह उपयोगकर्ता के लिए काफी पारदर्शी है, इसका मतलब है कि कोई भी नया डेटा (या हटाया गया डेटा!) हमेशा आपके डेटाबेस के डेटा के साथ समन्वयित नहीं होता है और इसलिए उपयोगकर्ता खोज पर तुरंत दिखाई नहीं देगा।
  • MySQL FULLTEXT खोज अच्छी और तेज़ है, लेकिन आपको पहले दो की सारी शक्ति और लचीलापन नहीं देगी।

कृपया बेझिझक टिप्पणी करें यदि मैं कुछ भूल गया/चूक गया।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. "त्रुटि 1136 (21S01)" को ठीक करें:MySQL में डेटा सम्मिलित करते समय कॉलम गणना पंक्ति 1 पर मान गणना से मेल नहीं खाती है"

  2. JPA के साथ जावा दिनांक को Mysql डेटाटाइम में कैसे संग्रहीत करें?

  3. क्या मैं पहचानकर्ता (तालिका या फ़ील्ड नाम) या सिंटैक्स कीवर्ड को बाध्य करने के लिए पीडीओ तैयार कथन का उपयोग कर सकता हूं?

  4. JSON_OBJECT () - MySQL में कुंजी/मान जोड़े की सूची से JSON ऑब्जेक्ट बनाएं

  5. MySQL पोर्ट एक्सेस को कैसे प्रतिबंधित करें