Simplify repo
This commit is contained in:
@@ -9,7 +9,7 @@ use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
|||||||
use Doctrine\ORM\Query;
|
use Doctrine\ORM\Query;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
class SearchIndexRepository extends ServiceEntityRepository
|
final class SearchIndexRepository extends ServiceEntityRepository
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param ManagerRegistry $registry
|
* @param ManagerRegistry $registry
|
||||||
@@ -19,99 +19,39 @@ class SearchIndexRepository extends ServiceEntityRepository
|
|||||||
parent::__construct($registry, SearchIndex::class);
|
parent::__construct($registry, SearchIndex::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves a SearchIndex entity
|
|
||||||
*
|
|
||||||
* @param SearchIndex $entity
|
|
||||||
* @param boolean $flush
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function add(SearchIndex $entity, bool $flush = false): void
|
|
||||||
{
|
|
||||||
$this->getEntityManager()->persist($entity);
|
|
||||||
|
|
||||||
if ($flush) {
|
|
||||||
$this->getEntityManager()->flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a SearchIndex entity
|
|
||||||
*
|
|
||||||
* @param SearchIndex $entity
|
|
||||||
* @param boolean $flush
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function remove(SearchIndex $entity, bool $flush = false): void
|
|
||||||
{
|
|
||||||
$this->getEntityManager()->remove($entity);
|
|
||||||
|
|
||||||
if ($flush) {
|
|
||||||
$this->getEntityManager()->flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a Query object ready to be paginated or used to present results.
|
* Returns a Query object ready to be paginated or used to present results.
|
||||||
*
|
|
||||||
* @param string $query
|
|
||||||
* @param integer $minScore
|
|
||||||
* @return Query
|
|
||||||
*/
|
*/
|
||||||
public function findAllPagination(string $query, int $minScore = 0): Query
|
public function findAllPagination(string $query, int $minScore = 0): Query
|
||||||
{
|
{
|
||||||
$qb = $this->createQueryBuilder('r')
|
return $this->createQueryBuilder('r')
|
||||||
->addSelect('MATCH(r.data) AGAINST(:searchText boolean) AS score')
|
->addSelect('MATCH(r.searchText) AGAINST(:searchText boolean) AS score')
|
||||||
->where(
|
->where('MATCH(r.searchText) AGAINST(:searchText boolean) > :minScore')
|
||||||
sprintf(
|
->orderBy('score', 'DESC')
|
||||||
'MATCH(r.data) AGAINST(:searchText boolean) > %f',
|
->setParameter('searchText', $this->convertSearchTerm($query))
|
||||||
$minScore
|
->setParameter('minScore', $minScore)
|
||||||
)
|
->getQuery();
|
||||||
)->orderBy('score', 'DESC')
|
|
||||||
->setParameter(
|
|
||||||
'searchText',
|
|
||||||
$this->convertSearchTerm($query)
|
|
||||||
);
|
|
||||||
return $qb->getQuery();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a string $query and explodes into individual words. Each word
|
* Splits the query into words and wraps each as `+WORD*`, so the fulltext
|
||||||
* is then prefixed with + and ends with *, making the full text search
|
* search requires every word and matches as a wildcard on each word's start.
|
||||||
* operate as wildcard on all words
|
|
||||||
*
|
|
||||||
* @param string $query
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
private function convertSearchTerm(string $query): string
|
private function convertSearchTerm(string $query): string
|
||||||
{
|
{
|
||||||
|
$sanitised = preg_replace('/[^\w\d]/', ' ', $query) ?? '';
|
||||||
|
$words = preg_split('/\s+/', $sanitised, -1, PREG_SPLIT_NO_EMPTY) ?: [];
|
||||||
|
|
||||||
$extractedWords = [];
|
$extractedWords = [];
|
||||||
$sanitisedString = preg_replace('/[^\w^\d]/', ' ', $query);
|
|
||||||
$words = mb_split('\s', preg_replace(['/([^\w+])/','/(\s+)/'], ' ', $sanitisedString));
|
|
||||||
|
|
||||||
foreach ($words as $word) {
|
foreach ($words as $word) {
|
||||||
if (strlen($word)< 1) {
|
$extractedWords[$word] = '+' . $word . '*';
|
||||||
//
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
$word = strtoupper($word);
|
|
||||||
$extractedWords[$word] = $word;
|
|
||||||
}
|
|
||||||
|
|
||||||
array_walk(
|
|
||||||
$extractedWords,
|
|
||||||
function(&$word) {
|
|
||||||
// require every word but allow matching just the start
|
|
||||||
$word = '+' . $word . '*';
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return implode(' ', $extractedWords);
|
return implode(' ', $extractedWords);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the index table of all results
|
* Clears the index table of all results
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function clearIndex(): void
|
public function clearIndex(): void
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user