mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
optimize query for person
This commit is contained in:
parent
6bc83edfe9
commit
f63d4fcfba
@ -19,6 +19,7 @@
|
||||
|
||||
namespace Chill\MainBundle\DependencyInjection;
|
||||
|
||||
use Chill\MainBundle\Doctrine\DQL\StrictWordSimilarityOPS;
|
||||
use Chill\MainBundle\Entity\UserJob;
|
||||
use Chill\MainBundle\Form\UserJobType;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
@ -185,6 +186,7 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface,
|
||||
'JSONB_EXISTS_IN_ARRAY' => JsonbExistsInArray::class,
|
||||
'SIMILARITY' => Similarity::class,
|
||||
'OVERLAPSI' => OverlapsI::class,
|
||||
'STRICT_WORD_SIMILARITY_OPS' => StrictWordSimilarityOPS::class
|
||||
],
|
||||
],
|
||||
'hydrators' => [
|
||||
|
@ -21,11 +21,6 @@ namespace Chill\MainBundle\Doctrine\DQL;
|
||||
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
|
||||
use Doctrine\ORM\Query\Lexer;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
class Similarity extends FunctionNode
|
||||
{
|
||||
private $firstPart;
|
||||
|
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\MainBundle\Doctrine\DQL;
|
||||
|
||||
use Doctrine\ORM\Query\Lexer;
|
||||
use Doctrine\ORM\Query\Parser;
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
|
||||
class StrictWordSimilarityOPS extends \Doctrine\ORM\Query\AST\Functions\FunctionNode
|
||||
{
|
||||
private $firstPart;
|
||||
|
||||
private $secondPart;
|
||||
|
||||
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
|
||||
{
|
||||
return $this->firstPart->dispatch($sqlWalker).
|
||||
' <<% ' . $this->secondPart->dispatch($sqlWalker);
|
||||
}
|
||||
|
||||
public function parse(\Doctrine\ORM\Query\Parser $parser)
|
||||
{
|
||||
$parser->match(Lexer::T_IDENTIFIER);
|
||||
$parser->match(Lexer::T_OPEN_PARENTHESIS);
|
||||
|
||||
$this->firstPart = $parser->StringPrimary();
|
||||
|
||||
$parser->match(Lexer::T_COMMA);
|
||||
|
||||
$this->secondPart = $parser->StringPrimary();
|
||||
|
||||
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
|
||||
}
|
||||
}
|
@ -12,7 +12,6 @@ use Doctrine\ORM\NonUniqueResultException;
|
||||
use Doctrine\ORM\NoResultException;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
|
||||
@ -126,7 +125,7 @@ final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterfac
|
||||
).'AS text'
|
||||
);
|
||||
} else {
|
||||
$qb->select('p');
|
||||
$qb->select('sp');
|
||||
}
|
||||
|
||||
$qb
|
||||
@ -254,18 +253,14 @@ final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterfac
|
||||
$grams = explode(' ', $pattern);
|
||||
|
||||
foreach($grams as $key => $gram) {
|
||||
$qb->andWhere('SIMILARITY(sp.fullnameCanonical, UNACCENT(LOWER(:default_'.$key.')) ) >= 0.15')
|
||||
$qb->andWhere('STRICT_WORD_SIMILARITY_OPS(:default_'.$key.', sp.fullnameCanonical) = TRUE')
|
||||
->setParameter('default_'.$key, '%'.$gram.'%');
|
||||
}
|
||||
|
||||
$qb->andWhere($qb->expr()
|
||||
->notIn(
|
||||
'sp.id',
|
||||
$this->createSearchQuery($pattern)
|
||||
->addSelect('p.id')
|
||||
->getDQL()
|
||||
)
|
||||
);
|
||||
// remove the perfect matches
|
||||
$qb->andWhere($qb->expr()
|
||||
->notLike('sp.fullnameCanonical', 'UNACCENT(LOWER(:not_default_'.$key.'))'))
|
||||
->setParameter('not_default_'.$key, '%'.$gram.'%');
|
||||
}
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ class SimilarityPersonSearch extends AbstractSearch
|
||||
protected function search(array $terms, $start, $limit, array $options = array())
|
||||
{
|
||||
return $this->personACLAwareRepository
|
||||
->findBySimilaritySearch($terms['_default']);
|
||||
->findBySimilaritySearch($terms['_default'], $start, $limit, $options['simplify'] ?? false);
|
||||
}
|
||||
|
||||
protected function count(array $terms)
|
||||
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\Migrations\Person;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Optimize trigram index on person fullname: create index for both center_id and fullname
|
||||
*/
|
||||
final class Version20210910161858 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Optimize trigram index on person fullname: create index for both center_id and fullname';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('DROP INDEX fullnamecanonical_trgm_idx');
|
||||
$this->addSql('CREATE INDEX fullnameCanonical_trgm_idx ON chill_person_person USING GIST (center_id, fullnameCanonical gist_trgm_ops)');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('DROP INDEX fullnamecanonical_trgm_idx');
|
||||
$this->addSql('CREATE INDEX fullnameCanonical_trgm_idx ON chill_person_person USING GIST (fullnameCanonical gist_trgm_ops)');
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user