implementation on 3party + quote keys in SearchApiQuery

This commit is contained in:
Julien Fastré 2021-06-28 22:44:42 +02:00
parent e845d9ba90
commit 0640631821
6 changed files with 77 additions and 12 deletions

View File

@ -4,9 +4,8 @@ namespace Chill\MainBundle\Search;
use Chill\MainBundle\Serializer\Model\Collection; use Chill\MainBundle\Serializer\Model\Collection;
use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Search\SearchPersonApiProvider; use Chill\PersonBundle\Search\SearchPersonApiProvider;
use Chill\ThirdPartyBundle\Entity\ThirdParty; use Chill\ThirdPartyBundle\Search\ThirdPartyApiSearch;
use Doctrine\DBAL\Types\Types; use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\ResultSetMappingBuilder; use Doctrine\ORM\Query\ResultSetMappingBuilder;
@ -18,21 +17,20 @@ use Symfony\Component\VarDumper\Resources\functions\dump;
class SearchApi class SearchApi
{ {
private EntityManagerInterface $em; private EntityManagerInterface $em;
private SearchProvider $search;
private PaginatorFactory $paginator; private PaginatorFactory $paginator;
private array $providers = []; private array $providers = [];
public function __construct( public function __construct(
EntityManagerInterface $em, EntityManagerInterface $em,
SearchProvider $search,
SearchPersonApiProvider $searchPerson, SearchPersonApiProvider $searchPerson,
ThirdPartyApiSearch $thirdPartyApiSearch,
PaginatorFactory $paginator PaginatorFactory $paginator
) )
{ {
$this->em = $em; $this->em = $em;
$this->search = $search;
$this->providers[] = $searchPerson; $this->providers[] = $searchPerson;
$this->providers[] = $thirdPartyApiSearch;
$this->paginator = $paginator; $this->paginator = $paginator;
} }
@ -47,11 +45,9 @@ class SearchApi
$paginator = $this->paginator->create($total); $paginator = $this->paginator->create($total);
$rawResults = $this->fetchRawResult($queries, $types, $parameters, $paginator); $rawResults = $this->fetchRawResult($queries, $types, $parameters, $paginator);
dump($rawResults);
$this->prepareProviders($rawResults); $this->prepareProviders($rawResults);
$results = $this->buildResults($rawResults); $results = $this->buildResults($rawResults);
dump($results);
$collection = new Collection($results, $paginator); $collection = new Collection($results, $paginator);
@ -169,8 +165,6 @@ class SearchApi
} }
} }
dump($items);
return $items ?? []; return $items ?? [];
} }
} }

View File

@ -0,0 +1,18 @@
<?php
namespace Chill\MainBundle\Search;
use Chill\MainBundle\Search\SearchApiQuery;
interface SearchApiInterface
{
public function provideQuery(string $pattern, array $parameters): SearchApiQuery;
public function supportsTypes(string $pattern, array $types, array $parameters): bool;
public function prepare(array $metadatas): void;
public function supportsResult(string $key, array $metadatas): bool;
public function getResult(string $key, array $metadata, float $pertinence);
}

View File

@ -58,7 +58,7 @@ class SearchApiQuery
public function buildQuery(): string public function buildQuery(): string
{ {
return \strtr("SELECT return \strtr("SELECT
{key} AS key, '{key}' AS key,
{metadata} AS metadata, {metadata} AS metadata,
{pertinence} AS pertinence {pertinence} AS pertinence
FROM {from} FROM {from}

View File

@ -4,8 +4,9 @@ namespace Chill\PersonBundle\Search;
use Chill\PersonBundle\Repository\PersonRepository; use Chill\PersonBundle\Repository\PersonRepository;
use Chill\MainBundle\Search\SearchApiQuery; use Chill\MainBundle\Search\SearchApiQuery;
use Chill\MainBundle\Search\SearchApiInterface;
class SearchPersonApiProvider class SearchPersonApiProvider implements SearchApiInterface
{ {
private PersonRepository $personRepository; private PersonRepository $personRepository;
@ -18,7 +19,7 @@ class SearchPersonApiProvider
{ {
$query = new SearchApiQuery(); $query = new SearchApiQuery();
$query $query
->setSelectKey("'person'") ->setSelectKey("person")
->setSelectJsonbMetadata("jsonb_build_object('id', person.id)") ->setSelectJsonbMetadata("jsonb_build_object('id', person.id)")
->setSelectPertinence("SIMILARITY(LOWER(UNACCENT(?)), person.fullnamecanonical)", [ $pattern ]) ->setSelectPertinence("SIMILARITY(LOWER(UNACCENT(?)), person.fullnamecanonical)", [ $pattern ])
->setFromClause("chill_person_person AS person") ->setFromClause("chill_person_person AS person")

View File

@ -0,0 +1,48 @@
<?php
namespace Chill\ThirdPartyBundle\Search;
use Chill\MainBundle\Search\SearchApiInterface;
use Chill\MainBundle\Search\SearchApiQuery;
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
class ThirdPartyApiSearch implements SearchApiInterface
{
private ThirdPartyRepository $thirdPartyRepository;
public function __construct(ThirdPartyRepository $thirdPartyRepository)
{
$this->thirdPartyRepository = $thirdPartyRepository;
}
public function provideQuery(string $pattern, array $parameters): SearchApiQuery
{
return (new SearchApiQuery)
->setSelectKey('tparty')
->setSelectJsonbMetadata("jsonb_build_object('id', tparty.id)")
->setSelectPertinence("SIMILARITY(?, LOWER(UNACCENT(tparty.name)))", [ $pattern ])
->setFromClause('chill_3party.third_party AS tparty')
->setWhereClause('SIMILARITY(LOWER(UNACCENT(?)), LOWER(UNACCENT(tparty.name))) > 0.20', [ $pattern ])
;
}
public function supportsTypes(string $pattern, array $types, array $parameters): bool
{
return \in_array('thirdparty', $types);
}
public function prepare(array $metadatas): void
{
}
public function supportsResult(string $key, array $metadatas): bool
{
return $key === 'tparty';
}
public function getResult(string $key, array $metadata, float $pertinence)
{
return $this->thirdPartyRepository->find($metadata['id']);
}
}

View File

@ -7,3 +7,7 @@ services:
$paginatorFactory: '@Chill\MainBundle\Pagination\PaginatorFactory' $paginatorFactory: '@Chill\MainBundle\Pagination\PaginatorFactory'
tags: tags:
- { name: 'chill.search', alias: '3party' } - { name: 'chill.search', alias: '3party' }
Chill\ThirdPartyBundle\Search\ThirdPartyApiSearch:
autowire: true
autoconfigure: true