2013-08-01 50 views
0

我有以下代碼在Laravel 4中搜索我的模型中的搜索短語。它使用'IN BOOLEAN MODE'和MATCH()和AGAINST()。MySQL/PHP布爾全文搜索問題Laravel 4

public function scopeSearch($query, $q) 
{ 
    $fields = Static::getFields(); 
    $fields = implode(', ', $fields); 

    $query->whereRaw("MATCH(" . $fields . ") AGAINST('" . $q . "' IN BOOLEAN MODE)"); 
} 

public static function getFields() 
{ 
    $field_names = array(); 
    $disallowed = array('id', 'created_at', 'updated_at', 'deleted_at'); 

    $columns = DB::select('SHOW COLUMNS FROM accounts'); 
    foreach ($columns as $c) { 
     $field = $c->Field; 
     if (! in_array($field, $disallowed)) { 
      $field_names[$field] = $field; 
     } 
    } 

    return $field_names; 
} 

我想幫助修改上面的代碼,允許用戶搜索使用部分單詞和短語的領域。例如,如果用戶輸入紫色,我希望搜索也能找到包含紫色字詞的電子郵件地址的任何記錄,因此請[email protected]。所以,基本上是部分匹配。

我還希望能夠在字段中找到包含griffon在內的所有類型短語john griffon,即使john不存在。

任何人都可以幫我解決這個問題嗎?乾杯。

+0

不能搜索與FULLTEXT隨機字符串,只有完整的單詞和單詞,XXX開始,如果你使用布爾模式。我不確定爲什麼它在您的情況下區分大小寫,但可能是因爲您在字段上具有區分大小寫的排序規則。 – Vatev

+0

整理是utf8_unicode_ci –

+0

這就是說我將如何更新我的代碼做我想要的然後,任何建議? –

回答

0

好的,我已盡最大努力用FULLTEXT搜索並使用通配符運算符搜索偏分量。這可能不是最好的解決方案,但它的工作原理。

public function scopeSearch($query, $q) 
{ 
    $fields = Static::getFields(); 
    $fields = implode(', ', $fields); 
    $terms = explode(' ', $q); 

    if (count($terms) > 1) { 
     $query->whereRaw("MATCH(" . $fields . ") AGAINST ('" . $q . "' IN BOOLEAN MODE)"); 
    } else { 
     foreach ($terms as $term) { 
      $query->whereRaw("MATCH(" . $fields . ") AGAINST ('*" . $term . "*' IN BOOLEAN MODE)"); 
     } 
    } 
} 

public static function getFields() 
{ 
    $field_names = array(); 
    $disallowed = array('id', 'country_id', 'created_at', 'updated_at', 'deleted_at'); 

    $columns = DB::select('SHOW COLUMNS FROM venues'); 
    foreach ($columns as $c) { 
     $field = $c->Field; 
     if (! in_array($field, $disallowed)) { 
      $field_names[$field] = $field; 
     } 
    } 

    return $field_names; 
} 

如果任何人都可以簡化或改善這一點,那麼我很樂意看到它。乾杯。

0

我得到的解決方案:

$terms = mysql_real_escape_string($terms); 

$contact_results = Contact::where_account_user_id(Auth::user()->account_user_id) 

->raw_where("match (`first`, `last`) against ('{$terms}*' IN BOOLEAN MODE)") 

->where_deleted(0) 

->paginate(20); 
phpconsole($contact_results->results); 

return $contact_results;