Skip to content

Instantly share code, notes, and snippets.

@ganey
Created April 19, 2018 14:45
Show Gist options
  • Save ganey/f67e0e742f6aa66e1634a9a90ae0561b to your computer and use it in GitHub Desktop.
Save ganey/f67e0e742f6aa66e1634a9a90ae0561b to your computer and use it in GitHub Desktop.
Illuminate/database (Laravel) full text search
<?php
namespace Models;
trait FullTextSearch
{
/**
* I did not write this! This is purely for reference
*
* Source: https://arianacosta.com/php/laravel/tutorial-full-text-search-laravel-5/
*
* define $searchable => [] columns on model, these must have a fulltext index
*/
/**
* Replaces spaces with full text search wildcards
*
* @param string $term
* @return string
*/
protected function fullTextWildcards($term)
{
// removing symbols used by MySQL
$reservedSymbols = ['-', '+', '<', '>', '@', '(', ')', '~'];
$term = str_replace($reservedSymbols, '', $term);
$words = explode(' ', $term);
foreach($words as $key => $word) {
/*
* applying + operator (required word) only big words
* because smaller ones are not indexed by mysql
*/
if(strlen($word) >= 3) {
$words[$key] = '+' . $word . '*';
}
}
$searchTerm = implode( ' ', $words);
return $searchTerm;
}
/**
* Scope a query that matches a full text search of term.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param string $term
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeSearch($query, $term)
{
$columns = implode(',',$this->searchable);
$searchableTerm = $this->fullTextWildcards($term);
//select all columns for the result using ->select('*')
return $query->select('*')->selectRaw("MATCH ({$columns}) AGAINST (? IN BOOLEAN MODE) AS relevance_score", [$searchableTerm])
->whereRaw("MATCH ({$columns}) AGAINST (? IN BOOLEAN MODE)", [$searchableTerm])
->orderBy('relevance_score','desc');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment