3
0

Simplify repo

This commit is contained in:
brabli
2026-05-07 17:29:54 +01:00
parent 38546292b6
commit df9b7f9bf1
+14 -74
View File
@@ -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
{ {