2013-03-12 4 views
10

मैं वर्तमान में इस कोड का उपयोग एकाधिक स्तंभों के खिलाफ खोज एक खोज के क्षेत्र है बनाने के लिए कैसे:एक बहु स्तंभ mysql की प्रतिलिपि प्राप्त खोज जहां आंशिक शब्दों का मिलान किया जाता है

$searchArray = explode(" ", $searchVal); 
$query="SELECT * FROM users WHERE "; 
$i=0; 
foreach ($searchArray as $word) { 
    if ($i != 0) $query .= " OR "; 
    $query .= " MATCH (`first_name`, `last_name`, `email`) AGAINST ('".$word."*' IN BOOLEAN MODE)"; 
    $i++; 
} 

चलें कहते हैं कि मैं तालिका में इन दोनों पंक्तियों है:

id | last_name | first_name | email 
1 | Smith  | John  | [email protected] 
2 | Smith  | Bob  | [email protected] 

यदि मैं "जॉन एस" टाइप करता हूं, तो केवल पहला परिणाम दिखाता है कि वांछित व्यवहार कौन सा है।

यदि मैं "जॉन स्मिथ" टाइप करता हूं, तो केवल पहला परिणाम दिखाता है कि वांछित व्यवहार कौन सा है।

यदि मैं "स्मिथ जे" टाइप करता हूं, तो दोनों परिणाम दिखाते हैं कि बॉब एक ​​मैच नहीं है।

यदि मैं "स्मिथ जॉन" टाइप करता हूं, तो दोनों परिणाम दिखाते हैं कि बॉब एक ​​मैच नहीं है।

आखिरकार, यदि मैं "जो एस" टाइप करता हूं, तो "जो" और "एस" पर आंशिक मिलान के बावजूद कोई परिणाम नहीं लौटाया जाता है।

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

अद्यतन:

बस अंतिम कोड है कि समाधान के आधार पर काम पोस्ट करने के लिए करना चाहता था। मेरा लूप एकाधिक मिलान कथन बना रहा था क्योंकि यह मेरा ft_min_word_len था।

मेरे कोड है:

$searchArray = explode(" ", $searchVal); 
$query="SELECT * FROM users WHERE MATCH (`first_name`, `last_name`, `email`) AGAINST ('"; 
$i=0; 
foreach ($searchArray as $word) { 
    $query .= "+".$word."* "; 
} 
$query .= "' IN BOOLEAN MODE)"; 

उत्तर

10

बूलियन मोड में जानने के लिए, (बजाय सिर्फ उच्च स्कोरिंग की) उपस्थित रहने की तार की आवश्यकता होती है, + साथ किया जाता है। उपसर्ग मिलान * के साथ किया जाता है।

+John* +S* 
+John* +Smith* 
+Smith* +J* 
+Jo* +S* 

ध्यान दें कि पूर्ण पाठ अनुक्रमणिका 'एक शब्द में कहीं भी' खोज आप मदद नहीं कर सकता: यह तुम क्या चाहते हो, तो के लिए खोज करने के लिए लगता है। तो *mith* की तरह कुछ विफल होने के लिए बाध्य है: वे एक सूचकांक में वर्ण 1 से मिलान करने के लिए हैं।

आप भी मैच मूल्यों से उन्हें ऑर्डर करने के लिए चाहते हैं, और उदाहरण के लिए, John Smithजरूरत से पहलेJohnny Smithson, यदि आप ऐसा करते हैं: जब तक आप जोड़ने

SELECT * FROM user 
WHERE MATCH(..fields..) AGAINST ('match' IN BOOLEAN MODE) 
ORDER BY MATCH(..fields..) AGAINST ('match' IN BOOLEAN MODE) DESC; 

कौन सा आप देखेंगे कहीं आप मिल जाएगा सभी शब्दों> = ft_min_word_len फिर से अलग:

+John* +S* John 
+John* +Smith* John Smith 
+Smith* +J* Smith 
+Jo* +S* 

पिछले एक के लिए, दोनों < डिफ़ॉल्ट 4 अक्षर हैं, इसलिए हम पी छँटाई नहीं जोड़ सकते डिफ़ॉल्ट रूप से mysql में इसके लिए arams, लेकिन आप ft_min_world_len सेट कर सकते हैं अलग-अलग वांछित है। "-"

+0

हालांकि अभी भी शर्तों के क्रम के साथ एक मुद्दा प्रतीत होता है। मैंने परीक्षण के लिए लंबा नाम प्राप्त करने के लिए पाब्लो पिकासो को डीबी में जोड़ा।"पाब्लो पिका" शब्द का परिणाम मिलता है। "पिका पाब्लो" नहीं करता है। क्या मुझे एक + और ए * के साथ एक एकल MATCH कथन में शर्तों का पूरा सेट पारित करना चाहिए या जैसा कि मैंने ऊपर दिया है या एक से अधिक MATCH स्टेटमेंट कर रहा हूं? – Max

+0

@ मैक्स: मैं इसे 'पिका पाब्लो' दोनों 'पाब्लो पिका' (या '+ पिका * + पाब्लो *'/'+ पाब्लो * + पिका *') के रूप में पुन: पेश नहीं कर सकता, मेरे लिए एक ही उपयोगकर्ता को वापस कर सकता हूं। हां, एक ही 'MATCH() के खिलाफ() 'कथन। 'MATCH()' में प्रत्येक एकल शब्द को 'टर्म * * प्रारूप की आवश्यकता होगी। हालांकि @ पैट्रिकबी की टिप्पणी पढ़ें: नाम <4 वर्ण कभी मेल नहीं खाएंगे। – Wrikken

+0

धन्यवाद! Ft_min_word_len का संयोजन और इसे एक एकल MATCH कथन में बदलकर इसे ठीक किया गया। मैं अपने अंतिम कोड के साथ सवाल अपडेट कर दूंगा। – Max

2

IN BOOLEAN MODE आप उपयोग कर सकते +NOT मजबूर करने के लिए AND या - -modifier मजबूर करने के लिए -modifier। कोई ऑपरेटर नहीं, आपका मामला, वैकल्पिक मतलब है।

और आपको अपने mysql कॉन्फ़िगरेशन में न्यूनतम शब्द लंबाई की जांच करने की आवश्यकता है ताकि FULLTEXT INDEX अनुक्रमणिका शब्दों को एक निश्चित लंबाई से छोटा बनाया जा सके।

मैं

ft_min_word_len = 2 
my.cnf में

स्थापित करने के लिए था और सूचकांक इस प्रभावी बनाने के लिए पुनर्निर्माण के लिए किया था। डिफ़ॉल्ट रूप से यह 3.

अपने min_word_len चेक (और वोट दें) this question

+1

फ़ील्ड 'ft_min_word_len' MATCH-query के लिए नहीं है, यह इंडेक्स के लिए है और क्वेरी अब मेल खा रही है। तो, जो स्मिथ नामक कोई व्यक्ति '+ जो * मैच से मेल नहीं खाता। –

+0

पहले से ही मेरी पहली टिप्पणी हटा दी गई है (क्योंकि यह झूठी थी, बूलियन मोड _does_ न्यूनतम शब्द लंबाई का उपयोग करें, इसके लिए मेरी माफ़ी)। – Wrikken

2

http://dev.mysql.com/doc/refman/5.5/en//fulltext-boolean.html

आप जगह एक "+", हो सकता है देखते हैं, या एक शब्द से पहले कोई ऑपरेटर इसके लिए खोज करने के लिए "और यह शब्द है", "नहीं इस शब्द शामिल है" और कोई ऑपरेटर "या यह शब्द है"

यदि मैं "जॉन एस" टाइप करता हूं, तो केवल पहला परिणाम दिखाता है कि वांछित व्यवहार कौन सा है।

वहाँ जो वांछित व्यवहार है अगर मैं "जॉन स्मिथ", केवल पहले परिणाम से पता चलता है में टाइप एस न्यूनतम शब्द लंबाई नीचे है और

त्याग दिया जाता है केवल एक ही जॉन है, तो यह काम करता है, ।

सिर्फ एक ही जॉन तो यह काम करता है

अगर मैं "स्मिथ जे" टाइप करें, दोनों परिणाम बताते हैं भले ही बॉब मिलान नहीं होती है।

जम्मू न्यूनतम शब्द लंबाई से कम है, इसलिए इसकी केवल स्मिथ मिलान जो दोनों पंक्तियों

अगर मैं टाइप "स्मिथ जॉन" है, दोनों परिणाम बताते हैं भले ही बॉब मिलान नहीं है।

चूंकि आप बुलेन मोड में हैं MySQL इसे स्मिथ या जॉन के रूप में व्याख्या करता है ... स्मिथ दोनों से मेल खाता है।

आखिरकार, यदि मैं "जो एस" टाइप करता हूं, तो "जो" और "एस" पर आंशिक मिलान के बावजूद कोई परिणाम नहीं लौटाया जाता है।

जो और एस कर रहे हैं कम से कम शब्द की लंबाई नीचे - मेरा मानना ​​है कि MySQL के लिए कुछ भी नहीं के लिए खोज के रूप में इस व्यवहार करता है

आप जोड़ना चाहें, एक "+" से पहले अपने खोज मापदंडों उन्हें एक और खोज में बदलने के लिए ... +Smith +John

+0

अभी भी शर्तों के आदेश के साथ एक मुद्दा प्रतीत होता है। मैंने पाब्लो पिकासो को डीबी में जोड़ा। "पाब्लो पिका" शब्द का परिणाम मिलता है। "पिका पाब्लो" नहीं करता है। क्या मुझे एक + और ए * के साथ एक एकल MATCH कथन में शर्तों का पूरा सेट पारित करना चाहिए या जैसा कि मैंने ऊपर दिया है या एक से अधिक MATCH स्टेटमेंट कर रहा हूं? – Max

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