Skip to content

Commit

Permalink
Refactor query builders
Browse files Browse the repository at this point in the history
  • Loading branch information
loevgaard committed Oct 10, 2024
1 parent b8549ad commit bb5a106
Show file tree
Hide file tree
Showing 15 changed files with 156 additions and 180 deletions.
23 changes: 23 additions & 0 deletions src/Config/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
use Psr\Container\ContainerInterface;
use Setono\SyliusMeilisearchPlugin\DataProvider\IndexableDataProviderInterface;
use Setono\SyliusMeilisearchPlugin\Document\Document;
use Setono\SyliusMeilisearchPlugin\Document\Metadata\MetadataFactoryInterface;
use Setono\SyliusMeilisearchPlugin\Document\Metadata\MetadataInterface;
use Setono\SyliusMeilisearchPlugin\Indexer\IndexerInterface;
use Setono\SyliusMeilisearchPlugin\Model\IndexableInterface;
use Setono\SyliusMeilisearchPlugin\Resolver\IndexName\IndexNameResolverInterface;

final class Index implements \Stringable
{
Expand Down Expand Up @@ -90,6 +93,26 @@ public function dataProvider(): IndexableDataProviderInterface
return $this->locator->get(IndexableDataProviderInterface::class);
}

/**
* Will return the index uid in Meilisearch based on the current context.
* This means you should not call this when you're not in a request/response context
*/
public function uid(): string

Check warning on line 100 in src/Config/Index.php

View check run for this annotation

Codecov / codecov/patch

src/Config/Index.php#L100

Added line #L100 was not covered by tests
{
/** @var IndexNameResolverInterface $indexNameResolver */
$indexNameResolver = $this->locator->get(IndexNameResolverInterface::class);

Check warning on line 103 in src/Config/Index.php

View check run for this annotation

Codecov / codecov/patch

src/Config/Index.php#L103

Added line #L103 was not covered by tests

return $indexNameResolver->resolve($this);

Check warning on line 105 in src/Config/Index.php

View check run for this annotation

Codecov / codecov/patch

src/Config/Index.php#L105

Added line #L105 was not covered by tests
}

public function metadata(): MetadataInterface

Check warning on line 108 in src/Config/Index.php

View check run for this annotation

Codecov / codecov/patch

src/Config/Index.php#L108

Added line #L108 was not covered by tests
{
/** @var MetadataFactoryInterface $metadataFactory */
$metadataFactory = $this->locator->get(MetadataFactoryInterface::class);

Check warning on line 111 in src/Config/Index.php

View check run for this annotation

Codecov / codecov/patch

src/Config/Index.php#L111

Added line #L111 was not covered by tests

return $metadataFactory->getMetadataFor($this->document);

Check warning on line 113 in src/Config/Index.php

View check run for this annotation

Codecov / codecov/patch

src/Config/Index.php#L113

Added line #L113 was not covered by tests
}

public function __toString(): string
{
return $this->name;
Expand Down
3 changes: 3 additions & 0 deletions src/DependencyInjection/SetonoSyliusMeilisearchExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Setono\SyliusMeilisearchPlugin\Indexer\DefaultIndexer;
use Setono\SyliusMeilisearchPlugin\Indexer\IndexerInterface;
use Setono\SyliusMeilisearchPlugin\Provider\IndexScope\IndexScopeProviderInterface;
use Setono\SyliusMeilisearchPlugin\Resolver\IndexName\IndexNameResolverInterface;
use Setono\SyliusMeilisearchPlugin\Twig\AutocompleteRuntime;
use Setono\SyliusMeilisearchPlugin\UrlGenerator\EntityUrlGeneratorInterface;
use Sylius\Bundle\ResourceBundle\DependencyInjection\Extension\AbstractResourceExtension;
Expand Down Expand Up @@ -279,6 +280,8 @@ private static function registerIndexesConfiguration(array $config, ContainerBui
ServiceLocatorTagPass::register($container, [
IndexableDataProviderInterface::class => new Reference($index['data_provider']),
IndexerInterface::class => new Reference($indexerServiceId),
IndexNameResolverInterface::class => new Reference('setono_sylius_meilisearch.resolver.index_name'),
MetadataFactoryInterface::class => new Reference(MetadataFactoryInterface::class),
]),
$index['prefix'],
]));
Expand Down
37 changes: 4 additions & 33 deletions src/Engine/SearchEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,52 +5,22 @@
namespace Setono\SyliusMeilisearchPlugin\Engine;

use Meilisearch\Client;
use Meilisearch\Contracts\SearchQuery;
use Meilisearch\Search\SearchResult;
use Setono\SyliusMeilisearchPlugin\Config\Index;
use Setono\SyliusMeilisearchPlugin\Document\Metadata\MetadataFactoryInterface;
use Setono\SyliusMeilisearchPlugin\Meilisearch\Filter\FilterBuilderInterface;
use Setono\SyliusMeilisearchPlugin\Meilisearch\Query\MainQueryBuilderInterface;
use Setono\SyliusMeilisearchPlugin\Meilisearch\Query\SubQueriesBuilderInterface;
use Setono\SyliusMeilisearchPlugin\Resolver\IndexName\IndexNameResolverInterface;
use Setono\SyliusMeilisearchPlugin\Meilisearch\Query\MultiSearchBuilderInterface;

final class SearchEngine implements SearchEngineInterface
{
public function __construct(

Check failure on line 14 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Backwards Compatibility Check

The parameter $metadataFactory of Setono\SyliusMeilisearchPlugin\Engine\SearchEngine#__construct() changed from Setono\SyliusMeilisearchPlugin\Document\Metadata\MetadataFactoryInterface to a non-contravariant Setono\SyliusMeilisearchPlugin\Config\Index

Check failure on line 14 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Backwards Compatibility Check

The parameter $filterBuilder of Setono\SyliusMeilisearchPlugin\Engine\SearchEngine#__construct() changed from Setono\SyliusMeilisearchPlugin\Meilisearch\Filter\FilterBuilderInterface to a non-contravariant Meilisearch\Client

Check failure on line 14 in src/Engine/SearchEngine.php

View workflow job for this annotation

GitHub Actions / Backwards Compatibility Check

The parameter $index of Setono\SyliusMeilisearchPlugin\Engine\SearchEngine#__construct() changed from Setono\SyliusMeilisearchPlugin\Config\Index to a non-contravariant Setono\SyliusMeilisearchPlugin\Meilisearch\Query\MultiSearchBuilderInterface
private readonly MetadataFactoryInterface $metadataFactory,
private readonly FilterBuilderInterface $filterBuilder,
private readonly Index $index,
private readonly IndexNameResolverInterface $indexNameResolver,
private readonly Client $client,
private readonly MainQueryBuilderInterface $mainQueryBuilder,
private readonly SubQueriesBuilderInterface $subQueriesBuilder,
private readonly MultiSearchBuilderInterface $multiSearchBuilder,
) {
}

public function execute(SearchRequest $searchRequest): SearchResult
{
$indexName = $this->indexNameResolver->resolve($this->index);
$metadata = $this->metadataFactory->getMetadataFor($this->index->document);
$facetsNames = $metadata->getFacetableAttributeNames();
$facets = $metadata->getFacetableAttributes();

/** @var array<string, mixed> $filters */
$filters = $this->filterBuilder->build($facets, $searchRequest->filters);

$mainQuery = $this->mainQueryBuilder->build(
$indexName,
$searchRequest->query ?? '',
$facetsNames,
$filters,
$searchRequest->page,
$searchRequest->sort ?? '',
);

/** @var list<SearchQuery> $queries */
$queries = array_merge(
[$mainQuery],
$this->subQueriesBuilder->build($indexName, $searchRequest->query ?? '', $facets, $searchRequest->filters),
);
$queries = $this->multiSearchBuilder->build($this->index, $searchRequest);

Check warning on line 23 in src/Engine/SearchEngine.php

View check run for this annotation

Codecov / codecov/patch

src/Engine/SearchEngine.php#L23

Added line #L23 was not covered by tests

/** @var array<SearchResult> $results */
$results = $this->client->multiSearch($queries)['results'] ?? [];
Expand All @@ -62,6 +32,7 @@ private function provideSearchResult(array $results): SearchResult
{
/** @var array{facetDistribution: array<string, int>} $firstResult */
$firstResult = current($results);

/** @psalm-suppress MixedArgument (just for now) */
$firstResult['facetDistribution'] = array_merge(...array_column($results, 'facetDistribution'));

Expand Down
1 change: 1 addition & 0 deletions src/Engine/SearchRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

final class SearchRequest
{
// todo we need the hits per page here
public function __construct(
public readonly ?string $query,
/** @var array<string, mixed> $filters */
Expand Down
2 changes: 1 addition & 1 deletion src/Meilisearch/Filter/FilterBuilderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ interface FilterBuilderInterface
* @param array<string, Facet> $facets
* @param array<string, mixed> $facetsValues
*
* @return array<string>
* @return list<string>
*/
public function build(array $facets, array $facetsValues): array;
}
41 changes: 0 additions & 41 deletions src/Meilisearch/Query/MainQueryBuilder.php

This file was deleted.

23 changes: 0 additions & 23 deletions src/Meilisearch/Query/MainQueryBuilderInterface.php

This file was deleted.

81 changes: 81 additions & 0 deletions src/Meilisearch/Query/MultiSearchBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusMeilisearchPlugin\Meilisearch\Query;

use Meilisearch\Contracts\SearchQuery;
use Setono\SyliusMeilisearchPlugin\Config\Index;
use Setono\SyliusMeilisearchPlugin\Document\Metadata\Facet;
use Setono\SyliusMeilisearchPlugin\Engine\SearchRequest;
use Setono\SyliusMeilisearchPlugin\Meilisearch\Filter\FilterBuilderInterface;

final class MultiSearchBuilder implements MultiSearchBuilderInterface
{
public function __construct(

Check warning on line 15 in src/Meilisearch/Query/MultiSearchBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/MultiSearchBuilder.php#L15

Added line #L15 was not covered by tests
private readonly SearchQueryBuilderInterface $searchQueryBuilder,
private readonly FilterBuilderInterface $filterBuilder,
private readonly int $hitsPerPage,
) {
}

public function build(Index $index, SearchRequest $searchRequest): array

Check warning on line 22 in src/Meilisearch/Query/MultiSearchBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/MultiSearchBuilder.php#L22

Added line #L22 was not covered by tests
{
$metadata = $index->metadata();
$facetsNames = $metadata->getFacetableAttributeNames();
$facets = $metadata->getFacetableAttributes();

Check warning on line 26 in src/Meilisearch/Query/MultiSearchBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/MultiSearchBuilder.php#L24-L26

Added lines #L24 - L26 were not covered by tests

$filters = $this->filterBuilder->build($facets, $searchRequest->filters);

Check warning on line 28 in src/Meilisearch/Query/MultiSearchBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/MultiSearchBuilder.php#L28

Added line #L28 was not covered by tests

return array_merge(
[$this->buildSearchQuery($index, $searchRequest, $facetsNames, $filters)],
$this->buildFacetQueries($index, $searchRequest, $facets, $searchRequest->filters),

Check warning on line 32 in src/Meilisearch/Query/MultiSearchBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/MultiSearchBuilder.php#L30-L32

Added lines #L30 - L32 were not covered by tests
);
}

/**
* @param list<string> $facetNames
* @param list<string> $filters
*/
private function buildSearchQuery(Index $index, SearchRequest $searchRequest, array $facetNames, array $filters): SearchQuery

Check warning on line 40 in src/Meilisearch/Query/MultiSearchBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/MultiSearchBuilder.php#L40

Added line #L40 was not covered by tests
{
$query = $this->searchQueryBuilder
->build($index->uid(), $searchRequest->query, $facetNames, $filters)
->setHitsPerPage($this->hitsPerPage)
->setPage($searchRequest->page)
;

Check warning on line 46 in src/Meilisearch/Query/MultiSearchBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/MultiSearchBuilder.php#L42-L46

Added lines #L42 - L46 were not covered by tests

if (null !== $searchRequest->sort) {
$query->setSort([$searchRequest->sort]);

Check warning on line 49 in src/Meilisearch/Query/MultiSearchBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/MultiSearchBuilder.php#L48-L49

Added lines #L48 - L49 were not covered by tests
}

return $query;

Check warning on line 52 in src/Meilisearch/Query/MultiSearchBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/MultiSearchBuilder.php#L52

Added line #L52 was not covered by tests
}

/**
* @param array<string, Facet> $facets
* @param array<string, mixed> $filters
*
* @return list<SearchQuery>
*/
private function buildFacetQueries(Index $index, SearchRequest $searchRequest, array $facets, array $filters): array

Check warning on line 61 in src/Meilisearch/Query/MultiSearchBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/MultiSearchBuilder.php#L61

Added line #L61 was not covered by tests
{
$searchQueries = [];

Check warning on line 63 in src/Meilisearch/Query/MultiSearchBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/MultiSearchBuilder.php#L63

Added line #L63 was not covered by tests

foreach ($facets as $facet) {

Check warning on line 65 in src/Meilisearch/Query/MultiSearchBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/MultiSearchBuilder.php#L65

Added line #L65 was not covered by tests
/** @var array<string, mixed> $filteredFacets */
$filteredFacets = array_filter($filters, static fn ($value) => $value !== $facet->name, \ARRAY_FILTER_USE_KEY);

Check warning on line 67 in src/Meilisearch/Query/MultiSearchBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/MultiSearchBuilder.php#L67

Added line #L67 was not covered by tests

$searchQueries[] = $this->searchQueryBuilder->build(
indexName: $index->uid(),
query: $searchRequest->query,
facets: [$facet->name],
filter: $this->filterBuilder->build($facets, $filteredFacets),
)
->setLimit(1)
;

Check warning on line 76 in src/Meilisearch/Query/MultiSearchBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/MultiSearchBuilder.php#L69-L76

Added lines #L69 - L76 were not covered by tests
}

return $searchQueries;

Check warning on line 79 in src/Meilisearch/Query/MultiSearchBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/MultiSearchBuilder.php#L79

Added line #L79 was not covered by tests
}
}
21 changes: 21 additions & 0 deletions src/Meilisearch/Query/MultiSearchBuilderInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusMeilisearchPlugin\Meilisearch\Query;

use Meilisearch\Contracts\SearchQuery;
use Setono\SyliusMeilisearchPlugin\Config\Index;
use Setono\SyliusMeilisearchPlugin\Engine\SearchRequest;

interface MultiSearchBuilderInterface
{
/**
* Will build a multi search query that handles the search and the facets
*
* todo explain somewhere why this is necessary
*
* @return list<SearchQuery>
*/
public function build(Index $index, SearchRequest $searchRequest): array;
}
12 changes: 9 additions & 3 deletions src/Meilisearch/Query/SearchQueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,19 @@

final class SearchQueryBuilder implements SearchQueryBuilderInterface
{
public function build(string $indexName, string $query, array $facets, array $filter): SearchQuery
public function build(string $indexName, ?string $query, array $facets, array $filter): SearchQuery

Check warning on line 11 in src/Meilisearch/Query/SearchQueryBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/SearchQueryBuilder.php#L11

Added line #L11 was not covered by tests
{
return (new SearchQuery())
$searchQuery = new SearchQuery();
$searchQuery

Check warning on line 14 in src/Meilisearch/Query/SearchQueryBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/SearchQueryBuilder.php#L13-L14

Added lines #L13 - L14 were not covered by tests
->setIndexUid($indexName)
->setQuery($query)
->setFacets($facets)
->setFilter($filter)
;

if (null !== $query) {
$searchQuery->setQuery($query);

Check warning on line 21 in src/Meilisearch/Query/SearchQueryBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/SearchQueryBuilder.php#L20-L21

Added lines #L20 - L21 were not covered by tests
}

return $searchQuery;

Check warning on line 24 in src/Meilisearch/Query/SearchQueryBuilder.php

View check run for this annotation

Codecov / codecov/patch

src/Meilisearch/Query/SearchQueryBuilder.php#L24

Added line #L24 was not covered by tests
}
}
4 changes: 2 additions & 2 deletions src/Meilisearch/Query/SearchQueryBuilderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface SearchQueryBuilderInterface
{
/**
* @param array<string> $facets
* @param array<string, mixed> $filter
* @param list<string> $filter
*/
public function build(string $indexName, string $query, array $facets, array $filter): SearchQuery;
public function build(string $indexName, ?string $query, array $facets, array $filter): SearchQuery;

Check failure on line 15 in src/Meilisearch/Query/SearchQueryBuilderInterface.php

View workflow job for this annotation

GitHub Actions / Backwards Compatibility Check

The parameter $query of Setono\SyliusMeilisearchPlugin\Meilisearch\Query\SearchQueryBuilderInterface#build() changed from string to string|null
}
33 changes: 0 additions & 33 deletions src/Meilisearch/Query/SubQueriesBuilder.php

This file was deleted.

23 changes: 0 additions & 23 deletions src/Meilisearch/Query/SubQueriesBuilderInterface.php

This file was deleted.

Loading

0 comments on commit bb5a106

Please sign in to comment.