Skip to content

Commit

Permalink
Refactor query build and implement sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
lruozzi9 committed Feb 27, 2024
1 parent e8dc218 commit fd94026
Show file tree
Hide file tree
Showing 18 changed files with 212 additions and 46 deletions.
12 changes: 12 additions & 0 deletions config/packages/monolog.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Symfony\Config\MonologConfig;

/** @psalm-suppress UndefinedClass */
return static function (MonologConfig $monolog): void {
$monolog->channels(['webgriffe_sylius_elasticsearch_plugin']);
};
19 changes: 19 additions & 0 deletions config/services/builder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Webgriffe\SyliusElasticsearchPlugin\Builder\TwigQueryBuilder;

return static function (ContainerConfigurator $containerConfigurator) {
$services = $containerConfigurator->services();

$services->set('webgriffe.sylius_elasticsearch_plugin.builder.query', TwigQueryBuilder::class)
->args([
service('twig'),
service('sylius.context.locale'),
service('monolog.logger.webgriffe_sylius_elasticsearch_plugin'),
])
;
};
1 change: 1 addition & 0 deletions config/services/controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
service('webgriffe.sylius_elasticsearch_plugin.provider.document_type'),
service('webgriffe.sylius_elasticsearch_plugin.parser.elasticsearch_document'),
service('form.factory'),
service('webgriffe.sylius_elasticsearch_plugin.builder.query'),
])
->call('setContainer', [service('service_container')])
->tag('controller.service_arguments')
Expand Down
18 changes: 18 additions & 0 deletions src/Builder/QueryBuilderInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Webgriffe\SyliusElasticsearchPlugin\Builder;

use Sylius\Component\Core\Model\TaxonInterface;

interface QueryBuilderInterface
{
/**
* @param array<string, string> $sorting
*/
public function buildTaxonQuery(
TaxonInterface $taxon,
array $sorting = [],
): array;
}
51 changes: 51 additions & 0 deletions src/Builder/TwigQueryBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace Webgriffe\SyliusElasticsearchPlugin\Builder;

use const JSON_THROW_ON_ERROR;
use Psr\Log\LoggerInterface;
use Sylius\Component\Core\Model\TaxonInterface;
use Sylius\Component\Locale\Context\LocaleContextInterface;
use Twig\Environment;

final readonly class TwigQueryBuilder implements QueryBuilderInterface
{
public function __construct(
private Environment $twig,
private LocaleContextInterface $localeContext,
private LoggerInterface $logger,
) {
}

public function buildTaxonQuery(
TaxonInterface $taxon,
array $sorting = [],
): array {
$query = $this->twig->render('@WebgriffeSyliusElasticsearchPlugin/query/taxon/query.json.twig', [
'taxon' => $taxon,
]);
$taxonQuery = [];
/** @var array $queryNormalized */
$queryNormalized = json_decode($query, true, 512, JSON_THROW_ON_ERROR);
$taxonQuery['query'] = $queryNormalized;
$localeCode = $this->localeContext->getLocaleCode();

foreach ($sorting as $field => $order) {
$sort = $this->twig->render('@WebgriffeSyliusElasticsearchPlugin/query/taxon/sort/' . $field . '.json.twig', [
'field' => $field,
'order' => $order,
'taxon' => $taxon,
'localeCode' => $localeCode,
]);
/** @var array $sortNormalized */
$sortNormalized = json_decode($sort, true, 512, JSON_THROW_ON_ERROR);
$taxonQuery['sort'][] = $sortNormalized;
}

$this->logger->debug(sprintf('Built taxon query: "%s".', json_encode($taxonQuery, JSON_THROW_ON_ERROR)));

return $taxonQuery;
}
}
2 changes: 1 addition & 1 deletion src/Client/ClientInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface ClientInterface extends LoggerAwareInterface
/**
* @throws CreateIndexException
*/
public function createIndex(string $name, array $mappings): void;
public function createIndex(string $name, array $mappings, array $settings): void;

/**
* @throws SwitchAliasException
Expand Down
7 changes: 5 additions & 2 deletions src/Client/ElasticsearchClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,14 @@ private function getLogger(): ?LoggerInterface
return $this->logger;
}

public function createIndex(string $name, array $mappings): void
public function createIndex(string $name, array $mappings, array $settings): void
{
$params = [
'index' => $name,
'body' => ['mappings' => $mappings],
'body' => [
'mappings' => $mappings,
'settings' => $settings,
],
];

try {
Expand Down
50 changes: 11 additions & 39 deletions src/Controller/ElasticsearchController.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Webgriffe\SyliusElasticsearchPlugin\Builder\QueryBuilderInterface;
use Webgriffe\SyliusElasticsearchPlugin\Client\ClientInterface;
use Webgriffe\SyliusElasticsearchPlugin\DocumentType\ProductDocumentType;
use Webgriffe\SyliusElasticsearchPlugin\Form\SearchType;
Expand All @@ -38,6 +39,7 @@ public function __construct(
private readonly DocumentTypeProviderInterface $documentTypeProvider,
private readonly DocumentParserInterface $documentParser,
private readonly FormFactoryInterface $formFactory,
private readonly QueryBuilderInterface $queryBuilder,
) {
}

Expand Down Expand Up @@ -91,7 +93,7 @@ public function searchAction(Request $request, ?string $query = null): Response
]);
}

public function taxonAction(string $slug): Response
public function taxonAction(Request $request, string $slug): Response
{
$localeCode = $this->localeContext->getLocaleCode();
$taxon = $this->taxonRepository->findOneBySlug($slug, $localeCode);
Expand All @@ -102,44 +104,14 @@ public function taxonAction(string $slug): Response
Assert::isInstanceOf($channel, ChannelInterface::class);

$productIndexAliasName = $this->indexNameGenerator->generateAlias($channel, $this->documentTypeProvider->getDocumentType(ProductDocumentType::CODE));
$query = [
'query' => [
'bool' => [
'must' => [
[
'nested' => [
'path' => 'taxons',
'query' => [
'bool' => [
'must' => [
[
'term' => [
'taxons.sylius-id' => $taxon->getId(),
],
],
],
],
],
],
],
[
'term' => [
'enabled' => true,
],
]
],
],
],
'sort' => [
['taxons.position' => [
'order' => 'asc',
'mode' => 'min',
'nested' => [
'path' => 'taxons',
],
]]
]
];

/** @var array<string, string> $sorting */
$sorting = $request->query->all('sorting');
if ($sorting === []) {
$sorting = ['position' => 'asc'];
}

$query = $this->queryBuilder->buildTaxonQuery($taxon, $sorting);
$result = $this->indexManager->query($query, [$productIndexAliasName]);
$responses = [];
/** @var array{_index: string, _id: string, score: float, _source: array} $hit */
Expand Down
3 changes: 3 additions & 0 deletions src/DocumentType/DocumentTypeInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,7 @@ public function getDocuments(ChannelInterface $channel): array;

/** @return array<string, array> */
public function getMappings(): array;

/** @return array<string, array> */
public function getSettings(): array;
}
19 changes: 17 additions & 2 deletions src/DocumentType/ProductDocumentType.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,21 @@ public function getDocuments(ChannelInterface $channel): array
return $documents;
}

public function getSettings(): array
{
return [
'analysis' => [
'analyzer' => [
'search_standard' => [
'type' => 'custom',
'tokenizer' => 'icu_tokenizer',
'filter' => ['lowercase', 'icu_folding', 'elision'],
],
],
],
];
}

public function getMappings(): array
{
return [
Expand Down Expand Up @@ -152,7 +167,7 @@ private static function nestedTranslationValues(bool $indexValue = true): array
'dynamic' => 'false',
'include_in_parent' => true,
'properties' => [
'locale' => self::text(false),
'locale' => self::text(),
'value' => self::keyword($indexValue),
],
];
Expand Down Expand Up @@ -271,7 +286,7 @@ private static function variantProperties(): array
'enabled' => true,
'subobjects' => true,
'properties' => self::priceProperties(),
]
],
];
}

Expand Down
2 changes: 1 addition & 1 deletion src/MessageHandler/CreateIndexHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function __invoke(CreateIndex $message): void
$aliasName = $this->indexNameGenerator->generateAlias($channel, $documentType);
$indexesToRemoveWildcard = $this->indexNameGenerator->generateWildcardPattern($channel, $documentType);

$this->indexManager->createIndex($indexName, $documentType->getMappings());
$this->indexManager->createIndex($indexName, $documentType->getMappings(), $documentType->getSettings());
$this->indexManager->bulk($indexName, $documentType->getDocuments($channel));
$this->indexManager->switchAlias($aliasName, $indexName);
$this->indexManager->removeIndexes($indexesToRemoveWildcard, [$indexName]);
Expand Down
2 changes: 1 addition & 1 deletion src/Serializer/ProductNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ private function normalizeProductTaxon(ProductTaxonInterface $productTaxon): arr

return array_merge(
$this->normalizeTaxon($taxon),
['position' => $productTaxon->getPosition()]
['position' => $productTaxon->getPosition()],
);
}

Expand Down
27 changes: 27 additions & 0 deletions templates/query/taxon/query.json.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"bool": {
"must": [
{
"nested": {
"path": "taxons",
"query": {
"bool": {
"must": [
{
"term": {
"taxons.sylius-id": "{{ taxon.id }}"
}
}
]
}
}
}
},
{
"term": {
"enabled": true
}
}
]
}
}
5 changes: 5 additions & 0 deletions templates/query/taxon/sort/createdAt.json.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"created-at": {
"order": "{{ order }}"
}
}
13 changes: 13 additions & 0 deletions templates/query/taxon/sort/name.json.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name.value": {
"order": "{{ order }}",
"nested": {
"path": "name",
"filter": {
"match": {
"name.locale": "{{ localeCode }}"
}
}
}
}
}
13 changes: 13 additions & 0 deletions templates/query/taxon/sort/position.json.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"taxons.position": {
"order": "{{ order }}",
"nested": {
"path": "taxons",
"filter": {
"term": {
"taxons.sylius-id": "{{ taxon.id }}"
}
}
}
}
}
9 changes: 9 additions & 0 deletions templates/query/taxon/sort/price.json.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"variants.price.price": {
"order": "{{ order }}",
"mode": "avg",
"nested": {
"path": "variants"
}
}
}
5 changes: 5 additions & 0 deletions tests/Application/config/packages/dev/monolog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ monolog:
firephp:
type: firephp
level: info
elasticsearch_plugin:
type: stream
path: "%kernel.logs_dir%/es_%kernel.environment%.log"
level: debug
channels: ["webgriffe_sylius_elasticsearch_plugin"]

0 comments on commit fd94026

Please sign in to comment.