2015-12-10 36 views
2

我希望你能幫助:)學說搜索字符串中的多個列

這是表的外觀:

+------------+----------------+------------------+---------+ 
| firstName | lastName  | email   | etc... | 
+------------+----------------+------------------+---------+ 
| John  | Doe   | [email protected]  | etc... | 
+------------+----------------+------------------+---------+ 
| John  | Michaels  | [email protected] | etc... | 
+------------+----------------+------------------+---------+ 

這是代碼的外觀:

if($_GET['search-customers'] != '') { 
    $busqueda = $_GET['search-customers']; 
    $query->andWhere("(c.firstName LIKE '%$busqueda%' OR c.lastName LIKE '%$busqueda%' OR c.email LIKE '%$busqueda%')"); 
} 

隨着QUERY:

  • 如果我輸入:約翰在搜索欄中,它給了我2結果。 OK
  • 如果我輸入:約翰·d在搜索框中,它並沒有給我任何結果。 FAIL

好吧,我明白了,當我鍵入「約翰·d」,它首先嚐試找到的firstName(不匹配),也它不匹配lastName的電子郵件

我該如何合併它們?

這個想法到找到所有可能性的完整字符串

謝謝!

回答

0

最後,我決定concateName和lastName。我排除了電子郵件然後查詢看起來像這樣:

$busqueda = $_GET['search-customers']; 
    $names = explode(' ',$busqueda); 
    $hasemail = strpos('@', $busqueda); 

    if ($hasemail) { 
     $query->andWhere("c.email LIKE '%$busqueda%'"); 
    } else { 
     $query->andWhere("(CONCAT(c.firstName,' ',c.lastName) LIKE '%$busqueda%' OR c.email LIKE '%$busqueda%')"); 
    } 
0

也許你可以使用explode功能是這樣的:

$busqueda = $_GET['search-customers']; 
$names = explode(' ',$busqueda); 
if(count($names)>1){ 
    $query->andWhere("(c.firstName LIKE '%{$names[0]}%' AND c.lastName LIKE '%{$names[1]}%')"); 
}else{ 
    $query->andWhere("(c.firstName LIKE '%$busqueda%' OR c.lastName LIKE '%$busqueda%' OR c.email LIKE '%$busqueda%')"); 
} 

但是,使用like %word%是低效的,因爲它不能使用索引。

+0

嗨,謝謝,但這隻會工作,如果第一個名字是一個簡單的單詞。例如,如果它的名字「馬林路德」和姓氏是「國王」,它將無法正常工作。謝謝你的幫助! –

+0

我想你最好提供兩個名稱搜索框。 –

4

我會用MySQL's Full-Text Search Functions爲您提供不同的選擇。讓我們開始準備表:現在

ALTER TABLE persons ADD FULLTEXT (`firstname`, `lastname`); 

firstnamelastname要通過全文以搜索匹配使用的列:

SELECT * FROM persons 
WHERE MATCH (firstname,lastname) 
AGAINST ('John D' IN NATURAL LANGUAGE MODE); 

結果將是:

+------------+----------------+------------------+---------+ 
| firstName | lastName  | email   | etc... | 
+------------+----------------+------------------+---------+ 
| John  | Doe   | [email protected]  | etc... | 
+------------+----------------+------------------+---------+ 
| John  | Michaels  | [email protected] | etc... | 
+------------+----------------+------------------+---------+ 

爲什麼這兩個?因爲找到了John(作爲一個詞),但John Doe位於第一行,因爲與搜索的術語有很多相似之處。

說,這可以應用這個工具與主義。我會假設你的模型是這樣的:

class Person{ 

    /** @column(type="string", name="firstname")*/ 
    protected $firstName; 

    /** @column(type="string", name="lastname")*/ 
    protected $lastName; 

    /** @column(type="string")*/ 
    protected $email; 
} 

讓我們創建的搜索功能:

public function search($term){ 
    $rsm = new ResultSetMapping(); 

    // Specify the object type to be returned in results 
    $rsm->addEntityResult('Models\Person', 'p'); 

    // references each attribute with table's columns 
    $rsm->addFieldResult('p', 'firstName', 'firstName'); 
    $rsm->addFieldResult('p', 'lastName', 'lastname'); 
    $rsm->addFieldResult('p', 'email', 'email'); 

    // create a native query 
    $sql = 'select p.firstName, p.lastname, p.email from persons p 
      where match(p.firstname, p.lastname) against(?)'; 

    // execute the query 
    $query = $em->createNativeQuery($sql, $rsm); 
    $query->setParameter(1, $term); 

    // getting the results 
    return $query->getResult(); 
} 

Finnally,以及例如:

$term = 'John D'; 
$results = search($term); 
// two results 
echo count($results); 

其他注意事項:

  1. 在mysql 5.7之前,只能添加全文MyISAM表。
  2. 只能索引CHAR,VARCHARTEXT列。
  3. 當在搜索中使用IN NATURAL LANGUAGE MODE時,當結果表示記錄的< 50%時,mysql返回空結果。