2011-08-09 21 views
1

我正在爲產品目錄創建搜索功能。

這是迄今爲止輸入代碼:

<form name="search" method="post" action="'.$PHP_SELF.'"> 
    <div> 
    Search for: <input type="text" name="find" /> 
    <input type="hidden" name="searching" value="yes" /> 
    <input type="submit" name="search" value="Search" /> 
    </div> 
</form> 

下面是查詢Mysql數據庫進行匹配查詢:

SELECT * FROM `products` WHERE upper(`desc`) LIKE'%$find%' 

這一切工作完全正常,當用戶搜索一個單詞字符串。

這裏的問題在於,當用戶搜索兩個字符串時,找不到匹配項,因爲有時這些字符串與單獨的特徵相關。

這方面的一個例子是,在產品目錄中包含各種巧克力的信息:

你得到的巧克力條,巧克力盒,巧克力的包,等等

現在雖然一些字段desc中的描述包含巧克力和酒吧,一些包含變體,如「公司酒吧120克巧克力」。

這會導致上述代碼中的問題,因爲如果用戶搜索「巧克力塊」,除非明確說明desc字段中包含該變體,則不會返回任何匹配。

我想要發生的事情是,當用戶搜索「巧克力棒」時,包含巧克力和酒吧的所有匹配項都會返回。

有沒有人有任何關於如何去做這項工作的意見?

可能性將$find轉換爲數組並使「」分隔符?

+1

這是什麼類別/標籤的用途。 –

+0

@Tomalak你好!我對此很新,但我會研究這些類別和標籤,感謝您的意見! –

+0

我的意思是你會創建它們,爲它們編制索引並搜索它們,而不是強迫自己通過人類可讀的「描述」進行搜索。 –

回答

1

也許你可以做這樣的事情:

$keywords_array = explode(' ', $find); 

$qry = "SELECT * FROM `products` WHERE `desc` LIKE '%" 
     . implode("%' OR `desc` LIKE '%", $keywords_array) 
     . "%'"; 

輸出爲$find = 'this'

SELECT * FROM products WHERE desc LIKE '%此%'

輸出爲$find = 'this and that'

SELECT * FROM products WHERE desc LIKE '%此%' OR desc LIKE '%和%' OR desc LIKE '%即%'

這肯定是一個非常基本的功能,但你的理念。

1

您需要將字符串拆分爲多個部分,然後分別將它們全部添加到where子句中。即:

.... WHERE `desc` LIKE '%bar%' OR `desc` LIKE '%chocolate%' 

但請注意,這可能是一個稍慢的查詢! SQL中的通配符搜索速度緩慢,而且多個通配符會導致問題複雜化。

您可以使用FULLTEXT獲得更快的結果。這需要額外的數據庫設置工作,但更重要的是,它可能在您給出的示例中沒有用,因爲FULLTEXT通常會從索引中刪除短字。它是可配置的,所以你可能會得到它的工作,但FULLTEXT的目的是爲大塊文本建立一個搜索索引;它並非真正用於較短的字符串。

對於這類問題更常見的解決方案是使用標記,並搜索標記而不是字符串。這將涉及基本上有一個單獨的表與每個記錄中的所有相關關鍵字,單獨存儲。這使您可以快速搜索,因爲您可以完全擺脫通配符。您甚至可以添加可能不在實際文本中的其他同義詞關鍵字,這可以幫助使搜索更容易使用。

如果您的用戶真的無法找到他們想要的標籤解決方案,您仍然可以給他們一個「高級」搜索,這可以追溯到通配符解決方案。只要確保他們知道它會很慢。

+0

而這不會做全文檢索。我寧願從輸入令牌構建一個聰明的FULLTEXT搜索。 –

+0

desc是一個保留字,請把它放在後面的蜱中。 – Jacob

+0

這就是我正在考慮的。但你確實提出了一個觀點。任何建議在一個更快的方法? –

1

你應該看看全文索引Documentation

desc LIKE '%word%' 是會得到越來越重。 用戶還可以提供2個字甚至更多。只需將查詢到更多的單詞,並建立一個where子句涵蓋所有posibilities:

WHERE desc LIKE '%word1%' or desc LIKE '%word2%' OR .... 

再次,這是不是很有效或快速,FULLTEXT +對陣工作得更好。

0

漂流到正則表達式怎麼樣?

您可以在$find|(或任何輸入語法你喜歡)代替空格來模擬 「OK」:

「巧克力」=> 「巧克力|欄」(甚至「\ b (巧克力|吧)\ b」如果你需要的字邊界)

,或者你可以轉換成以下,以模擬 「與」

「巧克力」=> 「巧克力*欄」

,然後執行:

WHERE desc REGEXP '$find'

雙檢,如果性能是你確定。

0

第一個問題是將搜索拆分爲單個單詞。這可以很容易地在PHP本身完成,但根據您的搜索,您可能也啓用了短語,例如, "this is a phrase" 如果不是,則只需將空格分隔搜索文本很容易。

對於第二個問題,已經發布了兩種可能的解決方案,或者您可以使用... LIKE 'chocolate% OR LIKE 'bar%(注意:我只在單詞後面添加了% - 我會避免在雙方都使用它,除非要將wordparts以及,例如hocol必須匹配巧克力。這是非常緩慢的,因爲索引不能使用!

更好的解決方案,如上所述將是fulltext search,使用MATCH()... AGAINST(),因爲此解決方案利用全文索引並加快您的搜索速度!