2013-03-11 74 views
1

當制定查詢以在自動填充表單(jquery Axax + PHP)中使用時,我有一個關於SQL最佳實踐的問題。自動完成SQL查詢建議(Ajax + PHP)

讓我們假設如下:

  • 我有書
  • 有些書的標題標題數據庫沒有一個明確的文章(以下簡稱「」或「A」),如「生活PI」
  • 有些書有一個明確的文章標題(以下簡稱‘’或‘A’),如‘麥田裏的守望者’

其結果是,用戶將輸入書名或者在開始時使用「The」或簡單省略「The」並開始查詢而沒有任何明確的文章。

三種可能的查詢似乎存在:

SELECT 'title' FROM 'books' WHERE 'title' LIKE '%$string' 

SELECT 'title' FROM 'books' WHERE 'title' LIKE '$string%' 

SELECT 'title' FROM 'books' WHERE 'title' LIKE '%$string%' 

當使用第一查詢方法(其中%是字符串之前),很難得到任何結果,因爲字符串之前的通配符似乎錯誤地行爲。

當使用第二個查詢時,它似乎傾向於在標題前使用「The」來完全匹配。因此,搜索「麥田守望者」的用戶將找到該書,但搜索「麥田守望者」的用戶不會。

最後一個結果是最好的結果,因爲它在字符串之前和之後都有一個通配符。但是,它也提供了最長的自動完成列表。用戶將不得不鍵入幾個字母來縮小搜索結果。

關於實現更高效查詢的任何想法?或者是第三個選項最好的一個(看到它是不可行的一本書的標題分開定冠詞?

由於提前,

回答

1
$query = mysqi_query("SELECT title FROM books WHERE title REGEXP '$string'"); 
if($query->num_rows() == 0) { 

    //First remove all the stop words like for, the, of, a from the search string. 
    $stopWords = array('/\bfor\b/i', '/\bthe\b/i', '/\bto\b/i', '/\bof\b/i','/\ba\b/i'); 
    $string = preg_replace($stopWords, "", $string); 

    //Then, use 
    mysqli_query("SELECT title FROM books WHERE title REGEXP '$string'"); 
} 
+0

這個我沒有想到,就像REGEX一樣,我會更深入地研究這個問題,但是,這可能會在一段時間後變得困難,畢竟,一些停用詞是標題的一部分。即「對於上帝和國家」 – 2013-03-11 20:20:24

+0

例如「對於上帝和國家」,如果你不爲'&'和'移除停用詞',你可能會拿出20個結果,你可能會拿出20個結果,但如果你刪除停用詞你可能只會得到5個結果。 – Girish 2013-03-11 20:26:23

0

如果你擔心的建議量,你是否可以修改更改事件以僅在字段中鍵入最小字符數量之後檢索建議?

+0

我想是這樣,但是這將是一個很好的標準? 2個字母? 3? – 2013-03-11 19:52:11

1

我建議在字符串的任一側使用第三種方法,如果您擔心的是大小返回的結果集可能會限制結果到一定數量,並且隨着用戶鍵入列表自然會變得更小和更具體。

1

你也可以考慮允許搜索'Catcher Rye',它應該仍然匹配。

在這種情況下 - 您會標記標題中的每個單詞以及用戶輸入的單詞並找到最佳匹配。

否則在輸入4個或更多字符後纔會自動完成,並使用選項3。

2

您可以使用正則表達式進行搜索(查詢結果會很快) 並且不要忘記對結果添加限制。

一個小例子

SELECT title FROM books WHERE title REGEXP '$string' LIMIT 20 

,或者您可以使用單詞邊界

SELECT title FROM books WHERE title REGEXP '[[:<:]]$string[[:>:]]' LIMIT 20 

看到文件http://dev.mysql.com/doc/refman/5.5/en/regexp.html

+0

謝謝我一定會深入研究REGEX作爲一個選項,它似乎與兩個通配符具有類似的行爲,除了它可能更強大(因爲它搜索模式)。 – 2013-03-11 20:17:30