Updating some terminology and variable names. Also updated readme to include more information about extending the package and fixed some spelling errors
This commit is contained in:
@ -17,16 +17,11 @@ class AcronymMatcher extends BaseMatcher
|
||||
protected $operator = 'LIKE';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $multiplier = 42;
|
||||
|
||||
/**
|
||||
* @param $searchString
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function formatSearchString( $searchString ) {
|
||||
|
||||
public function formatSearchString( $searchString )
|
||||
{
|
||||
return implode( '% ', str_split(strtoupper( $searchString ))) . '%';
|
||||
}
|
||||
}
|
@ -11,7 +11,8 @@ abstract class BaseMatcher implements MatcherInterface
|
||||
|
||||
protected $multiplier;
|
||||
|
||||
public function __construct( $multiplier ){
|
||||
public function __construct( $multiplier )
|
||||
{
|
||||
$this->multiplier = $multiplier;
|
||||
}
|
||||
|
||||
@ -22,8 +23,8 @@ abstract class BaseMatcher implements MatcherInterface
|
||||
* @param $searchString
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function buildQueryString( $column, $searchString ){
|
||||
|
||||
public function buildQueryString( $column, $searchString )
|
||||
{
|
||||
if ( method_exists($this, 'formatSearchString') )
|
||||
$searchString = $this->formatSearchString( $searchString );
|
||||
|
||||
|
@ -17,15 +17,11 @@ class ConsecutiveCharactersMatcher extends BaseMatcher
|
||||
protected $operator = 'LIKE';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $multiplier = 40;
|
||||
|
||||
/**
|
||||
* @param $searchString
|
||||
* @return string
|
||||
*/
|
||||
public function formatSearchString( $searchString ) {
|
||||
public function formatSearchString( $searchString )
|
||||
{
|
||||
return '%'.implode('%', str_split( $searchString )).'%';
|
||||
}
|
||||
|
||||
@ -34,8 +30,8 @@ class ConsecutiveCharactersMatcher extends BaseMatcher
|
||||
* @param $rawString
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function buildQueryString( $column, $rawString ){
|
||||
|
||||
public function buildQueryString( $column, $rawString )
|
||||
{
|
||||
$searchString = $this->formatSearchString( $rawString );
|
||||
|
||||
$query = "IF($column {$this->operator} '$searchString', ROUND({$this->multiplier} * (CHAR_LENGTH( '$rawString' ) / CHAR_LENGTH( REPLACE($column, ' ', '') ))), 0)";
|
||||
|
@ -11,14 +11,10 @@
|
||||
|
||||
class ExactMatcher extends BaseMatcher
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $operator = '=';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $multiplier = 100;
|
||||
|
||||
}
|
@ -18,15 +18,11 @@ class InStringMatcher extends BaseMatcher
|
||||
protected $operator = 'LIKE';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $multiplier = 30;
|
||||
|
||||
/**
|
||||
* @param $searchString
|
||||
* @return string
|
||||
*/
|
||||
public function formatSearchString( $searchString ){
|
||||
public function formatSearchString( $searchString )
|
||||
{
|
||||
return "%$searchString%";
|
||||
}
|
||||
}
|
@ -24,10 +24,9 @@ class LevenshteinMatcher extends BaseMatcher
|
||||
* @param $searchString
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function buildQueryString( $column, $searchString ){
|
||||
|
||||
public function buildQueryString( $column, $searchString )
|
||||
{
|
||||
return "levenshtein($column, '$searchString', {$this->sensitivity})";
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -18,15 +18,11 @@ class StartOfStringMatcher extends BaseMatcher
|
||||
protected $operator = 'LIKE';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $multiplier = 50;
|
||||
|
||||
/**
|
||||
* @param $searchString
|
||||
* @return string
|
||||
*/
|
||||
public function formatSearchString( $searchString ) {
|
||||
public function formatSearchString( $searchString )
|
||||
{
|
||||
return "$searchString%";
|
||||
}
|
||||
}
|
@ -18,15 +18,11 @@ class StartOfWordsMatcher extends BaseMatcher
|
||||
protected $operator = 'LIKE';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $multiplier = 35;
|
||||
|
||||
/**
|
||||
* @param $searchString
|
||||
* @return string
|
||||
*/
|
||||
public function formatSearchString( $searchString ) {
|
||||
public function formatSearchString( $searchString )
|
||||
{
|
||||
return implode('% ', explode(' ', $searchString)) . '%';
|
||||
}
|
||||
}
|
@ -17,21 +17,17 @@ class StudlyCaseMatcher extends BaseMatcher
|
||||
protected $operator = 'LIKE BINARY';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $multiplier = 32;
|
||||
|
||||
/**
|
||||
* @param $searchString
|
||||
* @return string
|
||||
*/
|
||||
public function formatSearchString( $searchString ) {
|
||||
public function formatSearchString( $searchString )
|
||||
{
|
||||
|
||||
return implode( '%', str_split(strtoupper( $searchString ))) . '%';
|
||||
}
|
||||
|
||||
public function buildQueryString( $column, $searchString ){
|
||||
|
||||
public function buildQueryString( $column, $searchString )
|
||||
{
|
||||
$query = "IF( CHAR_LENGTH( TRIM($column)) = CHAR_LENGTH( REPLACE( TRIM($column), ' ', '')) AND $column {$this->operator} '{$this->formatSearchString($searchString)}', {$this->multiplier}, 0)";
|
||||
|
||||
return $query;
|
||||
|
@ -14,17 +14,12 @@ class TimesInStringMatcher extends BaseMatcher
|
||||
{
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $multiplier = 8;
|
||||
|
||||
/**
|
||||
* @param $column
|
||||
* @param $searchString
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function buildQueryString( $column, $searchString ){
|
||||
|
||||
public function buildQueryString( $column, $searchString )
|
||||
{
|
||||
$query = "{$this->multiplier} * ROUND ((
|
||||
CHAR_LENGTH($column) - CHAR_LENGTH( REPLACE ( LOWER($column), lower('$searchString'), ''))
|
||||
) / LENGTH('$searchString'))";
|
||||
|
@ -10,8 +10,19 @@ use TomLingham\Searchy\SearchDrivers\FuzzySearchDriver;
|
||||
class SearchBuilder {
|
||||
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
private $table;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
private $searchFields;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
private $driverName;
|
||||
|
||||
/**
|
||||
@ -46,18 +57,19 @@ class SearchBuilder {
|
||||
public function driver( $driverName )
|
||||
{
|
||||
$this->driverName = $driverName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $table
|
||||
* @param $fields
|
||||
* @param $searchFields
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call( $table, $fields )
|
||||
public function __call( $table, $searchFields )
|
||||
{
|
||||
|
||||
return call_user_func_array([$this->search( $table ), 'fields'], $fields);
|
||||
return call_user_func_array([$this->search( $table ), 'fields'], $searchFields);
|
||||
|
||||
}
|
||||
|
||||
@ -66,13 +78,19 @@ class SearchBuilder {
|
||||
*/
|
||||
private function makeDriver()
|
||||
{
|
||||
if (! $this->driverName){
|
||||
$driverName = \Config::get('searchy::default');
|
||||
} else {
|
||||
// Check if default driver is being overridden, otherwise
|
||||
// load the default
|
||||
if ( $this->driverName ){
|
||||
$driverName = $this->driverName;
|
||||
} else {
|
||||
$driverName = \Config::get('searchy::default');
|
||||
}
|
||||
|
||||
// Gets the details for the selected driver from the configuration file
|
||||
$driverMap = \Config::get("searchy::drivers.$driverName");
|
||||
|
||||
// Create a new instance of the selected drivers 'class' and pass
|
||||
// through table and fields to search
|
||||
return new $driverMap['class']( $this->table, $this->searchFields );
|
||||
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ abstract class BaseSearchDriver implements SearchDriverInterface {
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fields;
|
||||
protected $searchFields;
|
||||
|
||||
/**
|
||||
* @var
|
||||
@ -25,10 +25,11 @@ abstract class BaseSearchDriver implements SearchDriverInterface {
|
||||
|
||||
/**
|
||||
* @param null $table
|
||||
* @param array $fields
|
||||
* @param array $searchFields
|
||||
*/
|
||||
public function __construct( $table = null, $fields = [] ){
|
||||
$this->fields = $fields;
|
||||
public function __construct( $table = null, $searchFields = [] )
|
||||
{
|
||||
$this->searchFields = $searchFields;
|
||||
$this->table = $table;
|
||||
}
|
||||
|
||||
@ -37,14 +38,15 @@ abstract class BaseSearchDriver implements SearchDriverInterface {
|
||||
* @return \Illuminate\Database\Query\Builder|mixed|static
|
||||
* @throws \Whoops\Example\Exception
|
||||
*/
|
||||
public function query( $searchString ){
|
||||
public function query( $searchString )
|
||||
{
|
||||
|
||||
if(\Config::get('searchy::sanitize'))
|
||||
$this->searchString = $this->sanitize($searchString);
|
||||
|
||||
$results = \DB::table($this->table)
|
||||
->select( \DB::raw('*') )
|
||||
->addSelect($this->buildSelectQuery( $this->fields ))
|
||||
->select('*')
|
||||
->addSelect($this->buildSelectQuery( $this->searchFields ))
|
||||
->orderBy(\Config::get('searchy::fieldName'), 'desc')
|
||||
->having(\Config::get('searchy::fieldName'),'>', 0);
|
||||
|
||||
@ -52,14 +54,16 @@ abstract class BaseSearchDriver implements SearchDriverInterface {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
* @param array $searchFields
|
||||
* @return array|\Illuminate\Database\Query\Expression
|
||||
*/
|
||||
protected function buildSelectQuery( array $fields ){
|
||||
protected function buildSelectQuery( array $searchFields )
|
||||
{
|
||||
|
||||
$query = [];
|
||||
|
||||
foreach ($fields as $field) {
|
||||
$query[] = $this->buildSelectCriteria( $field );
|
||||
foreach ($searchFields as $searchField) {
|
||||
$query[] = $this->buildSelectCriteria( $searchField );
|
||||
}
|
||||
|
||||
$query = \DB::raw(implode(' + ', $query) . ' AS ' . \Config::get('searchy::fieldName'));
|
||||
@ -68,14 +72,16 @@ abstract class BaseSearchDriver implements SearchDriverInterface {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $field
|
||||
* @param null $searchField
|
||||
* @return string
|
||||
*/
|
||||
protected function buildSelectCriteria( $field = null ) {
|
||||
protected function buildSelectCriteria( $searchField = null )
|
||||
{
|
||||
|
||||
$criteria = [];
|
||||
|
||||
foreach( $this->matchers as $matcher => $multiplier){
|
||||
$criteria[] = $this->makeMatcher( $field, $matcher, $multiplier );
|
||||
$criteria[] = $this->makeMatcher( $searchField, $matcher, $multiplier );
|
||||
}
|
||||
|
||||
return implode(' + ', $criteria);
|
||||
@ -83,17 +89,17 @@ abstract class BaseSearchDriver implements SearchDriverInterface {
|
||||
|
||||
|
||||
/**
|
||||
* @param $field
|
||||
* @param $searchField
|
||||
* @param $matcherClass
|
||||
* @param $multiplier
|
||||
* @return mixed
|
||||
*/
|
||||
protected function makeMatcher( $field, $matcherClass, $multiplier )
|
||||
protected function makeMatcher( $searchField, $matcherClass, $multiplier )
|
||||
{
|
||||
|
||||
$matcher = new $matcherClass( $multiplier );
|
||||
|
||||
return $matcher->buildQueryString( $field, $this->searchString );
|
||||
return $matcher->buildQueryString( $searchField, $this->searchString );
|
||||
|
||||
}
|
||||
|
||||
@ -101,7 +107,8 @@ abstract class BaseSearchDriver implements SearchDriverInterface {
|
||||
* @param $searchString
|
||||
* @return mixed
|
||||
*/
|
||||
private function sanitize( $searchString ) {
|
||||
private function sanitize( $searchString )
|
||||
{
|
||||
return preg_replace(\Config::get('searchy::sanitizeRegEx'), '', $searchString);
|
||||
}
|
||||
|
||||
|
42
src/res/levenshtein.sql
Normal file
42
src/res/levenshtein.sql
Normal file
@ -0,0 +1,42 @@
|
||||
DELIMITER $$
|
||||
DROP FUNCTION IF EXISTS levenshtein $$
|
||||
CREATE FUNCTION levenshtein( s1 VARCHAR(255), s2 VARCHAR(255), sensitivity INT )
|
||||
RETURNS INT
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT;
|
||||
DECLARE s1_char CHAR;
|
||||
-- max strlen=255
|
||||
DECLARE cv0, cv1 VARBINARY(256);
|
||||
SET s1_len = CHAR_LENGTH(s1), s2_len = CHAR_LENGTH(s2), cv1 = 0x00, j = 1, i = 1, c = 0;
|
||||
IF s1 = s2 THEN
|
||||
RETURN 0;
|
||||
ELSEIF s1_len = 0 THEN
|
||||
RETURN s2_len;
|
||||
ELSEIF s2_len = 0 THEN
|
||||
RETURN s1_len;
|
||||
ELSE
|
||||
WHILE j <= s2_len DO
|
||||
SET cv1 = CONCAT(cv1, UNHEX(HEX(j))), j = j + 1;
|
||||
END WHILE;
|
||||
WHILE i <= s1_len DO
|
||||
SET s1_char = SUBSTRING(s1, i, 1), c = i, cv0 = UNHEX(HEX(i)), j = 1;
|
||||
WHILE j <= s2_len DO
|
||||
SET c = c + 1;
|
||||
IF s1_char = SUBSTRING(s2, j, 1) THEN
|
||||
SET cost = 0; ELSE SET cost = 1;
|
||||
END IF;
|
||||
SET c_temp = CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + cost;
|
||||
IF c > c_temp THEN SET c = c_temp; END IF;
|
||||
SET c_temp = CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1;
|
||||
IF c > c_temp THEN
|
||||
SET c = c_temp;
|
||||
END IF;
|
||||
SET cv0 = CONCAT(cv0, UNHEX(HEX(c))), j = j + 1;
|
||||
END WHILE;
|
||||
SET cv1 = cv0, i = i + 1;
|
||||
END WHILE;
|
||||
END IF;
|
||||
RETURN c;
|
||||
END$$
|
||||
DELIMITER ;
|
Reference in New Issue
Block a user