forked from front/redisearch
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create class and methods for performing search operation
- Loading branch information
1 parent
77e02cd
commit e509041
Showing
5 changed files
with
268 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
<?php | ||
|
||
namespace FKRediSearch\RediSearch; | ||
|
||
use InvalidArgumentException; | ||
|
||
class Query { | ||
protected $return = ''; | ||
protected $summarize = ''; | ||
protected $highlight = ''; | ||
protected $expander = ''; | ||
protected $payload = ''; | ||
protected $limit = ''; | ||
protected $slop = null; | ||
protected $verbatim = ''; | ||
protected $withScores = ''; | ||
protected $withPayloads = ''; | ||
protected $noStopWords = ''; | ||
protected $noContent = ''; | ||
protected $inFields = ''; | ||
protected $inKeys = ''; | ||
protected $numericFilters = []; | ||
protected $geoFilters = []; | ||
protected $sortBy = ''; | ||
protected $scorer = ''; | ||
protected $language = ''; | ||
protected $client; | ||
private $indexName; | ||
|
||
public function __construct($client, $indexName) { | ||
$this->client = $client; | ||
$this->indexName = $indexName; | ||
} | ||
|
||
public function noContent() { | ||
$this->noContent = 'NOCONTENT'; | ||
return $this; | ||
} | ||
|
||
public function return($fields) { | ||
$count = empty( $fields ) ? 0 : count( $fields ); | ||
$field = implode(' ', $fields); | ||
$this->return = "RETURN $count $field"; | ||
return $this; | ||
} | ||
|
||
public function summarize( $fields, $fragmentCount = 3, $fragmentLength = 50, $separator = '...') { | ||
$count = empty($fields) ? 0 : count($fields); | ||
$field = implode(' ', $fields); | ||
$this->summarize = "SUMMARIZE FIELDS $count $field FRAGS $fragmentCount LEN $fragmentLength SEPARATOR $separator"; | ||
return $this; | ||
} | ||
|
||
public function highlight($fields, $openTag = '<strong>', $closeTag = '</strong>') { | ||
$count = empty($fields) ? 0 : count($fields); | ||
$field = implode(' ', $fields); | ||
$this->highlight = "HIGHLIGHT FIELDS $count $field TAGS $openTag $closeTag"; | ||
return $this; | ||
} | ||
|
||
public function expander( $expander ) { | ||
$this->expander = "EXPANDER $expander"; | ||
return $this; | ||
} | ||
|
||
public function payload( $payload) { | ||
$this->payload = "PAYLOAD $payload"; | ||
return $this; | ||
} | ||
|
||
public function limit( $offset, $pageSize = 10) { | ||
$this->limit = "LIMIT $offset $pageSize"; | ||
return $this; | ||
} | ||
|
||
public function inFields( $number, $fields) { | ||
$this->inFields = "INFIELDS $number " . implode(' ', $fields); | ||
return $this; | ||
} | ||
|
||
public function inKeys( $number, $keys) { | ||
$this->inKeys = "INKEYS $number " . implode(' ', $keys); | ||
return $this; | ||
} | ||
|
||
public function slop( $slop ) { | ||
$this->slop = "SLOP $slop"; | ||
return $this; | ||
} | ||
|
||
public function noStopWords() { | ||
$this->noStopWords = 'NOSTOPWORDS'; | ||
return $this; | ||
} | ||
|
||
public function withPayloads() { | ||
$this->withPayloads = 'WITHPAYLOADS'; | ||
return $this; | ||
} | ||
|
||
public function withScores() { | ||
$this->withScores = 'WITHSCORES'; | ||
return $this; | ||
} | ||
|
||
public function verbatim() { | ||
$this->verbatim = 'VERBATIM'; | ||
return $this; | ||
} | ||
|
||
public function numericFilter( $fieldName, $min, $max = null ) { | ||
$max = $max ?? '+inf'; | ||
$this->numericFilters[] = "@$fieldName:[$min $max]"; | ||
return $this; | ||
} | ||
|
||
public function geoFilter( $fieldName, $longitude, $latitude, $radius, $distanceUnit = 'km') { | ||
$geo_units = array( 'm', 'km', 'mi', 'ft' ); | ||
if ( !in_array($distanceUnit, $geo_units) ) { | ||
throw new InvalidArgumentException($distanceUnit); | ||
} | ||
|
||
$this->geoFilters[] = "@$fieldName:[$longitude $latitude $radius $distanceUnit]"; | ||
return $this; | ||
} | ||
|
||
public function sortBy( $fieldName, $order = 'ASC' ) { | ||
$this->sortBy = "SORTBY $fieldName $order"; | ||
return $this; | ||
} | ||
|
||
public function scorer( $scoringFunction ) { | ||
$this->scorer = "SCORER $scoringFunction"; | ||
return $this; | ||
} | ||
|
||
public function language( $languageName ) { | ||
$this->language = "LANGUAGE $languageName"; | ||
return $this; | ||
} | ||
|
||
public function searchQueryArgs( $query ) { | ||
$queryParts = array_merge([$query], $this->numericFilters, $this->geoFilters); | ||
$queryWithFilters = "'" . implode(' ', $queryParts) . "'"; | ||
return array_filter( | ||
array_merge( | ||
trim($queryWithFilters) === '' ? [$this->indexName] : [$this->indexName, $queryWithFilters], | ||
explode(' ', $this->limit), | ||
explode(' ', $this->slop), | ||
[ | ||
$this->verbatim, | ||
$this->withScores, | ||
$this->withPayloads, | ||
$this->noStopWords, | ||
$this->noContent, | ||
], | ||
explode(' ', $this->inFields), | ||
explode(' ', $this->inKeys), | ||
explode(' ', $this->return), | ||
explode(' ', $this->summarize), | ||
explode(' ', $this->highlight), | ||
explode(' ', $this->sortBy), | ||
explode(' ', $this->scorer), | ||
explode(' ', $this->language), | ||
explode(' ', $this->expander), | ||
explode(' ', $this->payload) | ||
), | ||
function ($item) { | ||
return !is_null($item) && $item !== ''; | ||
} | ||
); | ||
} | ||
|
||
public function search( $query = '', $documentsAsArray = false ) { | ||
$rawResult = $this->client->rawCommand( 'FT.SEARCH', $this->searchQueryArgs( $query ) ); | ||
|
||
return $rawResult ? SearchResult::searchResult( | ||
$rawResult, | ||
$documentsAsArray, | ||
$this->withScores !== '', | ||
$this->withPayloads !== '', | ||
$this->noContent !== '' | ||
) : new SearchResult(0, []); | ||
} | ||
|
||
public function explain( $query ) { | ||
return $this->client->rawCommand( 'FT.EXPLAIN', $this->searchQueryArgs( $query ) ); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
<?php | ||
namespace FKRediSearch\RediSearch; | ||
|
||
class SearchResult { | ||
protected $count; | ||
protected $documents; | ||
|
||
public function __construct( $count, $documents ) { | ||
$this->count = $count; | ||
$this->documents = $documents; | ||
} | ||
|
||
public function getCount() { | ||
return $this->count; | ||
} | ||
|
||
public function getDocuments() { | ||
return $this->documents; | ||
} | ||
|
||
public static function searchResult( $rawRediSearchResult, $documentsAsArray, $withScores = false, $withPayloads = false, $noContent = false ) { | ||
$docWidth = $noContent ? 1 : 2; | ||
if ( !$rawRediSearchResult ) { | ||
return false; | ||
} | ||
|
||
if ( count( $rawRediSearchResult ) === 1 ) { | ||
return new SearchResult( 0, [] ); | ||
} | ||
|
||
if ( $withScores ) { | ||
$docWidth++; | ||
} | ||
|
||
if ( $withPayloads ) { | ||
$docWidth++; | ||
} | ||
|
||
$count = array_shift( $rawRediSearchResult ); | ||
$documents = []; | ||
|
||
for ($i = 0; $i < count( $rawRediSearchResult ); $i += $docWidth ) { | ||
$document = $documentsAsArray ? [] : new \stdClass(); | ||
$documentsAsArray ? | ||
$document['id'] = $rawRediSearchResult[$i] : | ||
$document->id = $rawRediSearchResult[$i]; | ||
|
||
if ( $withScores ) { | ||
$documentsAsArray ? $document['score'] = $rawRediSearchResult[ $i + 1 ] : $document->score = $rawRediSearchResult[ $i + 1 ]; | ||
} | ||
|
||
if ($withPayloads) { | ||
$j = $withScores ? 2 : 1; | ||
$documentsAsArray ? | ||
$document['payload'] = $rawRediSearchResult[$i+$j] : | ||
$document->payload = $rawRediSearchResult[$i+$j]; | ||
} | ||
|
||
if (!$noContent) { | ||
$fields = $rawRediSearchResult[$i + ($docWidth - 1)]; | ||
|
||
if (is_array($fields)) { | ||
for ($j = 0; $j < count($fields); $j += 2) { | ||
$documentsAsArray ? $document[$fields[$j]] = $fields[$j + 1] : $document->{$fields[$j]} = $fields[$j + 1]; | ||
} | ||
} | ||
} | ||
|
||
$documents[] = $document; | ||
} | ||
|
||
return new SearchResult($count, $documents); | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters