2012-03-19 109 views
2

我正在爲一個小網站建立一個簡單的搜索引擎。用戶將能夠通過他們的email addressname搜索他們的朋友。我希望能夠使用FULLTEXT搜索,但我使用的是InnoDB表格,因此我可以回到LIKE %keyword%PHP/MySQL:簡單的搜索引擎

我的問題是,用戶有他們的名字和姓氏存儲在兩個單獨的列。我怎麼能去尋找「大衛規則」是這樣的情況?

這就是我目前所面對的:

if(filter_var($query,FILTER_VALIDATE_EMAIL)) { 
     $STH = $this->_db->prepare("SELECT UserID 
      FROM UserCredTable 
      WHERE EmailAddress = :query;"); 
    } else { 
     $STH = $this->_db->prepare("SELECT UserID 
      FROM UserInfoTable 
      WHERE FirstName LIKE :query 
      OR LastName LIKE :query;"); 
    } 

它有點工作,但我猜相關性是非常不存在:(

我如何排序最相關結果


更新:

這看起來像一個體面的解決方案嗎?

if(filter_var($query,FILTER_VALIDATE_EMAIL)) { 
     $params["query"] = $query; 
     $STH = $this->_db->prepare("SELECT UserID 
      FROM UserCredentials 
      WHERE EmailAddress = :query;"); 
    } else { 
     $params["query"] = "%".$query."%"; 
     $STH = $this->_db->prepare("SELECT UserID 
      FROM UserDetails 
      WHERE CONCAT(FirstName,' ',LastName) 
      LIKE :query;"); 
    } 
+0

它不會從性能的角度來看。這個查詢將無法使用索引,因此,對於大型表和/或大量使用它會使服務器變慢。儘管如此,小桌子還是可以的。 – 2012-03-19 18:07:53

+0

@YourCommonSense不會有比以往尋覓了六千多行。而且很少。這可以接受嗎? – 2012-03-19 18:29:00

+0

「非常罕見」意思是一天最多50次。 – 2012-03-19 18:36:34

回答

0

搜索顯然是一個很大的話題,並有許多不同的方式來處理事情。

這就是說,對於最基本的可能的解決方案,你應該能夠在這兩個領域的串聯搜索:

SELECT UserID 
     FROM UserInfoTable 
     WHERE CONCAT(FirstName, ' ', LastName) LIKE '%Dave Smith%'; 

CONCAT() MySQL的函數需要儘可能多的字符串作爲你串聯作爲參數。在上面的情況下,我們只是在之間加了一個空格,名字,姓氏

-1

您應該考慮在MySQL和許多其他數據庫引擎中使用全文搜索支持構建。

它爲您的搜索添加排名,這相當了不起。

下面的例子是從MySQL手冊,HTTP://dev.mysql.com/doc/refman/5.0/en/fulltext-natural-language.html

mysql> CREATE TABLE articles (
    -> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, 
    -> title VARCHAR(200), 
    -> body TEXT, 
    -> FULLTEXT (title,body) 
    ->) ENGINE=MyISAM; 
Query OK, 0 rows affected (0.00 sec) 

mysql> INSERT INTO articles (title,body) VALUES 
    -> ('MySQL Tutorial','DBMS stands for DataBase ...'), 
    -> ('How To Use MySQL Well','After you went through a ...'), 
    -> ('Optimizing MySQL','In this tutorial we will show ...'), 
    -> ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), 
    -> ('MySQL vs. YourSQL','In the following database comparison ...'), 
    -> ('MySQL Security','When configured properly, MySQL ...'); 
Query OK, 6 rows affected (0.00 sec) 
Records: 6 Duplicates: 0 Warnings: 0 

mysql> SELECT * FROM articles 
    -> WHERE MATCH (title,body) AGAINST ('database'); 
+----+-------------------+------------------------------------------+ 
| id | title    | body          | 
+----+-------------------+------------------------------------------+ 
| 5 | MySQL vs. YourSQL | In the following database comparison ... | 
| 1 | MySQL Tutorial | DBMS stands for DataBase ...    | 
+----+-------------------+------------------------------------------+ 
2 rows in set (0.00 sec) 
+1

*「我希望使用FULLTEXT搜索,但我使用的是InnoDB表格」* – Ryan 2012-03-19 15:58:50

+1

使用InnoDB – fire 2012-03-19 15:58:57

+0

+1不適用於正確的解決方案 – 2012-03-19 16:50:00

3

看看Sphinx它直接從MySQL索引數據,並有一個PHP API用於搜索。

除此之外,您可以分割搜索文本中的空格並嘗試一些OR,但像您說的,InnoDB中的相關性不存在。

MySQL並不是真正爲搜索設計的,所以使用另一種產品將會更加靈活和長期可擴展。

-1

可以使用CONCAT()函數在MySQL

} else { 
    $STH = $this->_db->prepare("SELECT UserID 
     FROM UserInfoTable 
     WHERE CONCAT(FirstName,LastName) LIKE '%:query%';"); 
} 
-1

如果全文搜索是不是一種選擇,那麼你很可能需要看劈裂搜索項和查詢這樣的事情:

SELECT UserID 
FROM UserInfoTable 
WHERE (FirstName LIKE '%David%' 
OR LastName LIKE '%David%') OR 
(FirstName LIKE '%:Rule%' 
OR LastName LIKE '%:Rule%') 

不理想,我不確定這是否是最佳解決方案,但它可能會爲您返回最佳結果集。特別是如果人們開始有三重桶裝名稱(如「約翰·泰勒史密斯」),這似乎是越來越普遍