0

I have the following code that searches my models in Laravel 4 for a search phrase. It uses 'IN BOOLEAN MODE' and MATCH() and AGAINST().

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;
}

I'd like help modifying the code above to allow a user to search the fields using partial words and phrases. For example, if a user types purple, I'd like the search to also find any records with email addresses containing the word purple, so info@purplegriffon.com. So, essentially partial matches.

I'd also like to be able to find everything containing griffon in the field for the typed phrase john griffon, even if john does not exist.

Can anyone help me out with this? Cheers.

4

2 回答 2

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;
}

如果有人可以简化或改进这一点,那么我很乐意看到它。干杯。

于 2013-08-01T14:54:53.240 回答
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;
于 2013-12-08T09:16:10.387 回答