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

MySQL बूलियन फुल-टेक्स्ट सर्च को कैसे ऑप्टिमाइज़ करें? (या इसे किसके साथ बदलना है?) - सी #

सबसे पहले, आपको यह महसूस करना चाहिए कि पूर्ण पाठ अनुक्रमण के लिए RDBMS समर्थन एक हैक है जो असंरचित पाठ से निपटने के लिए संरचित डेटा तक कुशल पहुंच की अनुमति देने के लिए डिज़ाइन की गई तकनीक को मजबूर करता है। (हां, यह सिर्फ मेरा है राय। यदि आवश्यक हो, तो मैं इसका बचाव कर सकता हूं क्योंकि मैं दोनों तकनीकों को बहुत अच्छी तरह समझता हूं।;)

तो, खोज प्रदर्शन को बेहतर बनाने के लिए क्या किया जा सकता है?

विकल्प एक - "कार्य के लिए सबसे अच्छा टूल"

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

उन कारणों के लिए जो नीचे स्पष्ट हो जाएंगे, मैं इस दृष्टिकोण की दृढ़ता से अनुशंसा करता हूं।

विकल्प दो - अपने परिणाम पहले से लोड करें

टेक्स्ट-आधारित खोज समाधानों का निर्माण करते समय, सामान्य दृष्टिकोण सभी दस्तावेज़ों को एक खोज योग्य अनुक्रमणिका में अनुक्रमित करना होता है और जबकि यह सबसे अधिक समीचीन हो सकता है, यह एकमात्र तरीका नहीं है।

यह मानते हुए कि आप जो खोज रहे हैं उसे आसानी से ज्ञात नियमों के एक सेट में परिमाणित किया जा सकता है, आप केवल अयोग्य पूर्ण-पाठ की तुलना में खोज की अधिक "निर्देशित" शैली की पेशकश कर सकते हैं। इससे मेरा तात्पर्य यह है कि, यदि आपका एप्लिकेशन उपयोगकर्ताओं को परिणामों के लिए निर्देशित करने से लाभान्वित हो सकता है, तो आप नियमों के ज्ञात सेट के आधार पर परिणामों के विभिन्न सेटों को उनकी अपनी तालिकाओं में प्रीलोड कर सकते हैं, और इस प्रकार खोजे जाने वाले डेटा की मात्रा को कम कर सकते हैं।

यदि आप उम्मीद करते हैं कि आपके अधिकांश उपयोगकर्ता किसी ज्ञात क्रम में खोज शब्दों के ज्ञात सेट से लाभान्वित होंगे, तो आप उन शब्दों के पक्ष में अपना खोज UI बना सकते हैं।

इसलिए यह मानते हुए कि अधिकांश उपयोगकर्ता विभिन्न प्रकार के ऑटोमोबाइल की तलाश कर रहे हैं, आप मॉडल, वर्ष, स्थिति आदि के आधार पर पूर्वनिर्धारित खोजों की पेशकश कर सकते हैं। आपका खोज UI उपयोगकर्ताओं को विशिष्ट परिणामों के लिए "मार्गदर्शित" करने के लिए ड्रॉपडाउन मेनू की एक श्रृंखला के रूप में तैयार किया जाएगा।

या यदि अधिकांश खोजें किसी विशिष्ट मुख्य विषय (जैसे 'ऑटोमोबाइल') के लिए होंगी, तो आप केवल उन्हीं रिकॉर्ड की तालिका को पूर्वनिर्धारित कर सकते हैं जिन्हें आपने पहले ऑटोमोबाइल से संबंधित होने के रूप में पहचाना है।

इन दोनों दृष्टिकोणों से खोजे जाने वाले रिकॉर्ड की संख्या कम हो जाएगी और इसलिए, प्रतिक्रिया समय में वृद्धि होगी।

विकल्प तीन - "अपना खुद का रोल करें"

यदि आप अपने प्रोजेक्ट में बाहरी खोज तकनीक को एकीकृत नहीं कर सकते हैं और प्रीलोडिंग एक विकल्प नहीं है, तो खोज क्वेरी प्रतिक्रिया समय में व्यापक सुधार करने के तरीके अभी भी हैं, लेकिन वे इस आधार पर भिन्न हैं कि आपको क्या हासिल करने की आवश्यकता है और आप कैसे खोजों की अपेक्षा करते हैं। ।

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

अपने मौजूदा डेटा से एक उल्टा इंडेक्स बनाने के लिए:

चरण 1. तीन टेबल बनाएं

    // dict - a dictionary containing one row per unique word in corpus  
    create table dict (    
      id int primary key,  
      word varchar  
    )

    // invert - an inverted_index to map words to records in corpus  
    create table invert (    
      id int primary key,  
      rec_id int,  
      word_id int  
    )

    // stopwords - to contain words to ignore when indexing (like a, an, the, etc)
    create table stopwords ( 
      id int primary key,  
      word varchar  
    )

नोट:यह सिर्फ एक स्केच है। जब आप वास्तव में ये तालिकाएँ बनाते हैं, तो आप अनुक्रमणिका और अवरोध आदि जोड़ना चाहेंगे।

स्टॉपवर्ड तालिका का उपयोग आपकी अनुक्रमणिका के आकार को केवल उन शब्दों तक कम करने के लिए किया जाता है जो उपयोगकर्ताओं की अपेक्षित क्वेरी के लिए मायने रखते हैं। उदाहरण के लिए, 'ए', 'ए', 'द' जैसे अंग्रेजी लेखों को अनुक्रमित करना शायद ही कभी उपयोगी होता है, क्योंकि वे कीवर्ड खोजों में उपयोगी अर्थ का योगदान नहीं करते हैं।

आमतौर पर, आपको विशेष रूप से तैयार की गई . स्टॉपवर्ड सूची की आवश्यकता होगी आपके आवेदन की जरूरतों के लिए। यदि आप कभी भी उपयोगकर्ताओं से अपनी क्वेरी में 'लाल', 'सफेद' या 'नीला' शब्दों को शामिल करने की अपेक्षा नहीं करते हैं या यदि ये शब्द प्रत्येक में दिखाई देते हैं खोजने योग्य रिकॉर्ड, आप उन्हें अपनी स्टॉपवर्ड सूची में जोड़ना चाहेंगे।

MySQL में अपनी स्वयं की स्टॉपवर्ड सूची का उपयोग करने के निर्देशों के लिए इस संदेश के अंत में नोट देखें।

यह भी देखें:

चरण 2. उलटा इंडेक्स बनाएं

अपने मौजूदा रिकॉर्ड से एक उल्टा इंडेक्स बनाने के लिए, आपको (छद्म कोड) की आवश्यकता होगी:

    foreach( word(w) in record(r) ) {
      if(w is not in stopwords) {
        if( w does not exist in dictionary) {
          insert w to dictionary at w.id
        }
        insert (r.id, w.id) into inverted_index
      }
    }
. में स्टॉपवर्ड पर अधिक:

एक विशिष्ट स्टॉपवर्ड सूची का उपयोग करने के बजाय, 'if(w is not in stopwords)' परीक्षण आपकी अस्वीकार्य शब्दों की सूची के बजाय या उसके सहायक के रूप में अन्य निर्णय ले सकता है।

हो सकता है कि आपका आवेदन 4 वर्णों से कम के सभी शब्दों को फ़िल्टर करना चाहे या केवल शामिल करें एक पूर्वनिर्धारित सेट से शब्द।

अपना खुद का उलटा सूचकांक बनाकर, आप खोज पर कहीं अधिक और बेहतर नियंत्रण प्राप्त करते हैं।

चरण 3. SQL का उपयोग करके उल्टे अनुक्रमणिका को क्वेरी करें

यह कदम वास्तव में इस बात पर निर्भर करता है कि आप अपनी अनुक्रमणिका में प्रश्नों को कैसे सबमिट करने की अपेक्षा करते हैं।

यदि प्रश्नों को 'हार्ड-कोडेड' किया जाना है, तो आप केवल स्वयं चयन कथन बना सकते हैं या यदि आपको उपयोगकर्ता द्वारा दर्ज किए गए प्रश्नों का समर्थन करने की आवश्यकता है, तो आपको जो भी क्वेरी भाषा चुनी गई है उसे SQL कथन में परिवर्तित करने की आवश्यकता होगी (आमतौर पर एक का उपयोग करके किया जाता है सरल पार्सर)।

यह मानते हुए कि आप तार्किक क्वेरी '(वर्ड1 और वर्ड2) या वर्ड3' से मेल खाने वाले सभी दस्तावेजों को पुनः प्राप्त करना चाहते हैं, एक संभावित तरीका यह हो सकता है:

CREATE TEMPORARY TABLE temp_results ( rec_id int, count int ) AS 
    ( SELECT rec_id, COUNT(rec_id) AS count 
      FROM invert AS I, dict AS D 
      WHERE I.word_id=D.id AND (D.word='word1' OR D.word='word2') 
      GROUP BY I.rec_id 
      HAVING count=2
    ) 
    UNION (
      SELECT rec_id, 1 AS count 
      FROM invert AS I, dict AS D
      WHERE I.word_id=D.id AND D.word='word3'
    );

SELECT DISTINCT rec_id FROM temp_results;

DROP TABLE temp_results;

नोट:यह मेरे सिर के ऊपर से सिर्फ एक पहला पास है। मुझे विश्वास है कि बूलियन क्वेरी एक्सप्रेशन को एक कुशल SQL कथन में बदलने के अधिक कुशल तरीके हैं और सुधार के लिए किसी भी और सभी सुझावों का स्वागत करते हैं।

वाक्यांशों की खोज करने के लिए, आपको उल्टे सूचकांक में एक फ़ील्ड जोड़ने की आवश्यकता होगी ताकि यह शब्द अपने रिकॉर्ड में दिखाई देने वाली स्थिति और आपके चयन में कारक को दर्शा सके।

और अंत में, जैसे ही आप नए रिकॉर्ड जोड़ते हैं या पुराने को हटाते हैं, आपको अपनी उलटी अनुक्रमणिका को अपडेट करना होगा।

अंतिम शब्द

"पूर्ण पाठ खोज" अनुसंधान के एक बहुत बड़े क्षेत्र के अंतर्गत आता है जिसे "सूचना पुनर्प्राप्ति" या आईआर के रूप में जाना जाता है और इस विषय पर कई पुस्तकें हैं, जिनमें शामिल हैं

अधिक के लिए अमेज़न देखें।

नोट

MySQL में अपने स्वयं के स्टॉपवर्ड्स की सूची का उपयोग कैसे करें

MySQL में अपनी स्वयं की स्टॉपवर्ड सूची का उपयोग करने के लिए:

  1. स्टॉपवर्ड की अपनी सूची बनाएं, प्रति पंक्ति एक शब्द, और इसे अपने सर्वर पर किसी ज्ञात स्थान पर सहेजें, जैसे:/usr/local/lib/IR/stopwords.txt

  2. निम्न पंक्तियों को जोड़ने या अपडेट करने के लिए my.cnf संपादित करें:
        [mysqld]  
        ft_min_word_len=1    
        ft_max_word_len=40  
        ft_stopword_file=/usr/local/lib/IR/stopwords.txt
    

    जो कानूनी शब्दों की न्यूनतम और अधिकतम लंबाई को क्रमशः 1 और 40 पर सेट करेगा, और mysqld को बताएगा कि स्टॉपवर्ड की आपकी कस्टम सूची कहां मिलेगी।

    (नोट:डिफ़ॉल्ट ft_max_word_len 84 है, जो मुझे लगता है कि बहुत अधिक है और स्ट्रिंग के रन का कारण बन सकता है जो वास्तविक शब्दों को अनुक्रमित करने के लिए नहीं हैं।)

  3. mysqld को पुनरारंभ करें

  4. सभी पूर्ण-पाठ संबंधित सूचकांकों को छोड़ें और पुन:बनाएँ



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. डेटाबेस प्रशासकों के लिए 15 मूल MySQL साक्षात्कार प्रश्न

  2. किसी अन्य संग्रहीत कार्यविधि में mysql संग्रहीत कार्यविधि के परिणाम सेट का उपयोग करें

  3. तारीखों और एसयूएम मूल्यों के आधार पर Django समूह

  4. Mac पर PDO MySQL ड्राइवर

  5. लगातार विज़िट की संख्या गिनें