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. * * @param string $query * @param integer $minScore * @return Query */ public function findAllPagination(string $query, int $minScore = 0): Query { $qb = $this->createQueryBuilder('r') ->addSelect('MATCH(r.data) AGAINST(:searchText boolean) AS score') ->where( sprintf( 'MATCH(r.data) AGAINST(:searchText boolean) > %f', $minScore ) )->orderBy('score', 'DESC') ->setParameter( 'searchText', $this->convertSearchTerm($query) ); return $qb->getQuery(); } /** * Takes a string $query and explodes into individual words. Each word * is then prefixed with + and ends with *, making the full text search * operate as wildcard on all words * * @param string $query * @return string */ private function convertSearchTerm(string $query): string { $extractedWords = []; $sanitisedString = preg_replace('/[^\w^\d]/', ' ', $query); $words = mb_split('\s', preg_replace(['/([^\w+])/','/(\s+)/'], ' ', $sanitisedString)); foreach ($words as $word) { if (strlen($word)< 1) { // 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); } /** * Clears the index table of all results * @return void */ public function clearIndex(): void { $this ->createQueryBuilder('s') ->delete() ->getQuery() ->execute(); } }