MySQL मैच () विरुद्ध () - प्रासंगिकता और कॉलम द्वारा आदेश?


80

ठीक है, इसलिए मैं कई स्तंभों में एक पूर्ण पाठ खोज बनाने की कोशिश कर रहा हूं, कुछ इस तरह सरल:

SELECT * FROM pages WHERE MATCH(head, body) AGAINST('some words' IN BOOLEAN MODE)

अब मैं प्रासंगिकता से आदेश देना चाहता हूं, (शब्दों में से कितने पाए जाते हैं?) जो मैं कुछ इस तरह से कर पाया हूं:

SELECT * , MATCH (head, body) AGAINST ('some words' IN BOOLEAN MODE) AS relevance 
FROM pages
WHERE MATCH (head, body) AGAINST ('some words' IN BOOLEAN MODE)
ORDER BY relevance

अब यहां वह हिस्सा आता है जहां मैं खो जाता हूं, मैं headकॉलम में प्रासंगिकता को प्राथमिकता देना चाहता हूं ।

मुझे लगता है कि मैं दो प्रासंगिक कॉलम बना सकता हूं, एक के लिए headऔर एक के लिए body, लेकिन उस बिंदु पर मैं तालिका में तीन बार कुछ हद तक एक ही खोज कर रहा हूं, और इस फ़ंक्शन को बनाने के लिए, प्रदर्शन महत्वपूर्ण है, क्योंकि मैं क्वेरी को अन्य तालिकाओं के साथ जोड़ा और मिलान किया जाएगा।

तो, मेरा मुख्य सवाल यह है कि क्या प्रासंगिकता की खोज करने और कुछ स्तंभों को प्राथमिकता देने का एक तेज़ तरीका है? (और एक बोनस के रूप में संभवतया प्रासंगिकता बनाते हुए भी कॉलम में शब्दों की संख्या कितनी बार होती है?)

किसी भी सुझाव या सलाह बहुत अच्छा होगा।

नोट: मैं इसे एक LAMP- सर्वर पर चला रहा हूँ। (स्थानीय परीक्षण में WAMP)


क्या आपको वास्तव में MATCH ... AGECTST को सेलेक्ट क्लॉज और WHERE क्लॉज दोनों में रखना है ? क्या आप इसे सेलेक्ट क्लॉज में अलियास नहीं कर सकते हैं और ऐलिस को WHERE क्लॉज में रेफर कर सकते हैं? मैं तैयार किए गए बयानों का उपयोग करने की कोशिश कर रहा हूं और यह मुझे बेमानी / अजीब लगता है।
एस।

2
नहीं, जैसा कि 5.5 के बाद से MySQL प्रलेखन में कहा गया है, MATCH ... AGAINST की गणना एक बार की जाएगी जब दोनों SELECT और WHERE में होंगे, इसलिए कोई अतिरिक्त ओवरहेड नहीं होगा।
212 बजे बॉब 2

जवाबों:


156

यह आपके इच्छित शीर्ष भाग को बढ़ी हुई प्रासंगिकता दे सकता है । यह इसे दोगुना नहीं करेगा, लेकिन यह संभवतः आपके लिए बहुत अच्छा हो सकता है:

SELECT pages.*,
       MATCH (head, body) AGAINST ('some words') AS relevance,
       MATCH (head) AGAINST ('some words') AS title_relevance
FROM pages
WHERE MATCH (head, body) AGAINST ('some words')
ORDER BY title_relevance DESC, relevance DESC

-- alternatively:
ORDER BY title_relevance + relevance DESC

एक विकल्प जिसे आप भी जांचना चाहते हैं, यदि आप DB इंजन को स्विच करने के लिए लचीलापन रखते हैं, तो Postgres है । यह ऑपरेटरों के वजन को निर्धारित करने और रैंकिंग के साथ खेलने की अनुमति देता है।


14
एक तरफ के रूप में, MySQL 5.6 InnoDB तालिकाओं पर पूर्ण पाठ खोजों का समर्थन करता है!
जाबरी

1
क्या आप इसके लिए SQL फिडेल प्रदान कर सकते हैं?
उपयोगकर्ता

एकाधिक खोजों पर नकारात्मक प्रभाव कितना होता है? मुझे 4 मैचों की आवश्यकता होगी आयन मेरे चयन के रूप में मैं 4 अलग वजन कारक है। क्या इससे प्रदर्शन कम होगा?
टोबे

@ToBe मैंने इसी तरह के अन्य सवालों पर देखा है कि एक से अधिक लोग कहते हैं कि MATCHMySQL के आंतरिक रूप से काम करने के तरीके के कारण कई बयानों का उपयोग करने के साथ कोई अतिरिक्त ओवरहेड नहीं है ।
BadHorsie

सुनिश्चित करें कि आप इन दोनों को चलाते हैं। ALTER TABLE talk_webpages ADD FULLTEXT(head)औरALTER TABLE talk_webpages ADD FULLTEXT(head, body)
सुपुन कवींडा

15

बस जरूरत है जो जोड़ने के लिए .. तालिका को बदलने के लिए मत भूलना!

ALTER TABLE table_name ADD FULLTEXT(column_name);

3
यदि आप एक से अधिक बार कमांड निष्पादित करते हैं, तो यह एक ही कॉलम (एस) के लिए कई इंडेक्स बनाएगा। इसलिए इस कमांड को केवल एक बार चलाएं।
19

बेहतर अभी तक, टैबलेन (कॉलम_नाम (एस)) पर क्रिएट फुलटेक्स इंडेक्स इंडेक्स का उपयोग करें। यदि आप इसे बनाने का प्रयास करते हैं, तो आपको वास्तव में जांचना चाहिए कि क्या सूचकांक मौजूद है। यदि आप इसका उपयोग करते हुए मौजूद हैं, तो आप इसकी जांच कर सकते हैं: INFROMATION_SCHEMA.STATISTICS WHERE TABLE_CATALOG= 'def' और TABLE_SCHEMA= DATABASE () और TABLE_NAME= 'tablename' AND INDEX_NAME= 'indexname' का चयन करें: INDEX_NAME से;
डेव हिल्डिच

9

मैंने ऐसा कभी नहीं किया है, लेकिन ऐसा लगता है

MATCH (head, head, body) AGAINST ('some words' IN BOOLEAN MODE)

सिर में पाए जाने वाले मैचों को दोहरा वजन देना चाहिए


डॉक्स पृष्ठ पर इस टिप्पणी को पढ़ें , सोचा कि यह आपके लिए महत्वपूर्ण हो सकता है:

9 दिसंबर 2002 6:51 पर पैट्रिक ओ'लोन द्वारा पोस्ट किया गया

प्रलेखन में यह ध्यान दिया जाना चाहिए कि IN BOOLEAN MODE लगभग हमेशा 1.0 की प्रासंगिकता लौटाएगा। सार्थक होने के लिए प्रासंगिकता प्राप्त करने के लिए, आपको निम्नलिखित की आवश्यकता होगी:

SELECT MATCH('Content') AGAINST ('keyword1 keyword2') as Relevance 
FROM table 
WHERE MATCH ('Content') AGAINST('+keyword1+keyword2' IN BOOLEAN MODE) 
HAVING Relevance > 0.2 
ORDER BY Relevance DESC 

ध्यान दें कि जब आप BOOLEAN MODE का उपयोग करते हैं, तो WHERE क्लॉज़ के साथ संयुक्त प्रासंगिक कारकों को प्राप्त करने के लिए आप एक नियमित प्रासंगिकता क्वेरी कर रहे हैं। BOOLEAN MODE आपको सब्मिट देता है जो BOOLEAN खोज की आवश्यकताओं को पूरा करता है, प्रासंगिकता क्वेरी प्रासंगिकता कारक को पूरा करती है, और HAVING क्लॉज (इस मामले में) यह सुनिश्चित करता है कि दस्तावेज़ खोज से संबंधित है (अर्थात दस्तावेज़ जो 0.2 से कम स्कोर करते हैं अप्रासंगिक माना जाता है)। यह आपको प्रासंगिकता से ऑर्डर करने की अनुमति भी देता है।

यह उस तरह से एक बग नहीं हो सकता है जिस तरह से BOOLEAN MODE संचालित होता है, हालांकि मैंने मेलिंग सूची पर जो टिप्पणियां पढ़ी हैं, वे बताती हैं कि IN BOOLEAN MODE की प्रासंगिकता रैंकिंग बहुत जटिल नहीं है, इस प्रकार वास्तव में प्रासंगिक दस्तावेजों के लिए खुद को खराब रूप से उधार देना है। BTW - मैंने ऐसा करने के लिए एक प्रदर्शन हानि पर ध्यान नहीं दिया, क्योंकि यह प्रतीत होता है कि MySQL केवल एक बार FULLTEXT खोज करता है, भले ही दो MATCH खंड अलग-अलग हों। इसे साबित करने के लिए EXPLAIN का उपयोग करें।

तो ऐसा लगता है कि आपको दो बार फुलटेक्स्ट सर्च को कॉल करने के बारे में चिंता करने की आवश्यकता नहीं हो सकती है, हालांकि आपको "साबित करने के लिए EXPLAIN का उपयोग" करना चाहिए


1
मैच में दो बार सिर जोड़ना () कार्य दुख की बात नहीं है। हो सकता है क्योंकि क्वेरी शब्दों की संख्या की गणना नहीं कर रही है? और मैं उस पृष्ठ का उपयोग कर रहा हूं जिसे आप अच्छी तरह से संदर्भित करते हैं, लेकिन मैं किसी कारण से इसे काम नहीं कर सकता ... मैंने अभी तक अपने स्तंभों को अनुक्रमित नहीं किया है, और इसके बाद "IN IN BOEEAN MODE 'टैग के बिना खोज नहीं कर सकता। ।
क्रिस्टोफर ला कोर्ट

मुझे लगता है कि एक गैर-बोलेन खोज # घटनाओं की # वापसी करेगी, लेकिन बोलेन नहीं?
जिसास्टोन

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

मुझे BOOLEAN MODE का उपयोग करने में समस्या हो रही थी और फिर प्रासंगिकता से आदेश दिया और इस समस्या को प्रासंगिकता के साथ हमेशा हल किया। 1. धन्यवाद।
Jazzy

स्कोर फ़ील्ड बनाने से मेरा मुद्दा हल हो गया: मुझे परिणाम मिल रहे थे, लेकिन उनमें से बहुत सारे शोर थे। धन्यवाद, +1
क्रिस बेकर

4

मैं बस इसके साथ खेल रहा था, भी। एक तरह से आप अतिरिक्त वजन जोड़ सकते हैं कोड के ORDER BY क्षेत्र में है।

उदाहरण के लिए, यदि आप 3 अलग-अलग कॉलमों का मिलान कर रहे थे और अधिक भारी वज़न वाले कुछ कॉलमों को प्राप्त करना चाहते थे:

SELECT search.*,
MATCH (name) AGAINST ('black' IN BOOLEAN MODE) AS name_match,
MATCH (keywords) AGAINST ('black' IN BOOLEAN MODE) AS keyword_match,
MATCH (description) AGAINST ('black' IN BOOLEAN MODE) AS description_match
FROM search
WHERE MATCH (name, keywords, description) AGAINST ('black' IN BOOLEAN MODE)
ORDER BY (name_match * 3  + keyword_match * 2  + description_match) DESC LIMIT 0,100;

क्या यह वास्तव में भारी क्वेरी नहीं है?
बीनो

5
गणित को चुनिंदा कथन में ले जाएँ और यह लोड को बहुत हल्का करता है। SELECT search.*, (MATCH (name) AGAINST ('black' IN BOOLEAN MODE) * 3) + (MATCH (keywords) AGAINST ('black' IN BOOLEAN MODE)*2 + MATCH (description) AGAINST ('black' IN BOOLEAN MODE)) AS totalScore , FROM search WHERE MATCH (name, keywords, description) AGAINST ('black' IN BOOLEAN MODE) ORDER BY totalScore DESC LIMIT 0,100;
उल्टास्पीकर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.