vendor/shopware/elasticsearch/Framework/ElasticsearchHelper.php line 231

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Elasticsearch\Framework;
  3. use Elasticsearch\Client;
  4. use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery;
  5. use ONGR\ElasticsearchDSL\Query\FullText\MatchQuery;
  6. use ONGR\ElasticsearchDSL\Search;
  7. use Psr\Log\LoggerInterface;
  8. use Shopware\Core\Framework\Context;
  9. use Shopware\Core\Framework\DataAbstractionLayer\EntityDefinition;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
  13. use Shopware\Elasticsearch\Exception\ServerNotAvailableException;
  14. use Shopware\Elasticsearch\Exception\UnsupportedElasticsearchDefinitionException;
  15. use Shopware\Elasticsearch\Framework\DataAbstractionLayer\CriteriaParser;
  16. class ElasticsearchHelper
  17. {
  18.     // max for default configuration
  19.     public const MAX_SIZE_VALUE 10000;
  20.     private Client $client;
  21.     private ElasticsearchRegistry $registry;
  22.     private CriteriaParser $parser;
  23.     private bool $searchEnabled;
  24.     private bool $indexingEnabled;
  25.     private string $environment;
  26.     private LoggerInterface $logger;
  27.     private string $prefix;
  28.     private bool $throwException;
  29.     public function __construct(
  30.         string $environment,
  31.         bool $searchEnabled,
  32.         bool $indexingEnabled,
  33.         string $prefix,
  34.         bool $throwException,
  35.         Client $client,
  36.         ElasticsearchRegistry $registry,
  37.         CriteriaParser $parser,
  38.         LoggerInterface $logger
  39.     ) {
  40.         $this->client $client;
  41.         $this->registry $registry;
  42.         $this->parser $parser;
  43.         $this->searchEnabled $searchEnabled;
  44.         $this->indexingEnabled $indexingEnabled;
  45.         $this->environment $environment;
  46.         $this->logger $logger;
  47.         $this->prefix $prefix;
  48.         $this->throwException $throwException;
  49.     }
  50.     /**
  51.      * @deprecated tag:v6.5.0 - use logAndThrowException instead
  52.      */
  53.     public function logOrThrowException(\Throwable $exception): bool
  54.     {
  55.         return $this->logAndThrowException($exception);
  56.     }
  57.     public function logAndThrowException(\Throwable $exception): bool
  58.     {
  59.         $this->logger->critical($exception->getMessage());
  60.         if ($this->environment === 'test') {
  61.             throw $exception;
  62.         }
  63.         if ($this->environment !== 'dev') {
  64.             return false;
  65.         }
  66.         if ($this->throwException) {
  67.             throw $exception;
  68.         }
  69.         return false;
  70.     }
  71.     /**
  72.      * Created the index alias
  73.      */
  74.     public function getIndexName(EntityDefinition $definitionstring $languageId): string
  75.     {
  76.         return $this->prefix '_' $definition->getEntityName() . '_' $languageId;
  77.     }
  78.     public function allowIndexing(): bool
  79.     {
  80.         if (!$this->indexingEnabled) {
  81.             return false;
  82.         }
  83.         if (!$this->client->ping()) {
  84.             return $this->logOrThrowException(new ServerNotAvailableException());
  85.         }
  86.         return true;
  87.     }
  88.     /**
  89.      * Validates if it is allowed do execute the search request over elasticsearch
  90.      */
  91.     public function allowSearch(EntityDefinition $definitionContext $context): bool
  92.     {
  93.         if (!$this->searchEnabled) {
  94.             return false;
  95.         }
  96.         if (!$this->isSupported($definition)) {
  97.             return false;
  98.         }
  99.         if (!$context->hasState(Context::STATE_ELASTICSEARCH_AWARE)) {
  100.             return false;
  101.         }
  102.         return true;
  103.     }
  104.     public function handleIds(EntityDefinition $definitionCriteria $criteriaSearch $searchContext $context): void
  105.     {
  106.         $ids $criteria->getIds();
  107.         if (empty($ids)) {
  108.             return;
  109.         }
  110.         $query $this->parser->parseFilter(
  111.             new EqualsAnyFilter('id'array_values($ids)),
  112.             $definition,
  113.             $definition->getEntityName(),
  114.             $context
  115.         );
  116.         $search->addQuery($queryBoolQuery::FILTER);
  117.     }
  118.     public function addFilters(EntityDefinition $definitionCriteria $criteriaSearch $searchContext $context): void
  119.     {
  120.         $filters $criteria->getFilters();
  121.         if (empty($filters)) {
  122.             return;
  123.         }
  124.         $query $this->parser->parseFilter(
  125.             new MultiFilter(MultiFilter::CONNECTION_AND$filters),
  126.             $definition,
  127.             $definition->getEntityName(),
  128.             $context
  129.         );
  130.         $search->addQuery($queryBoolQuery::FILTER);
  131.     }
  132.     public function addPostFilters(EntityDefinition $definitionCriteria $criteriaSearch $searchContext $context): void
  133.     {
  134.         $postFilters $criteria->getPostFilters();
  135.         if (empty($postFilters)) {
  136.             return;
  137.         }
  138.         $query $this->parser->parseFilter(
  139.             new MultiFilter(MultiFilter::CONNECTION_AND$postFilters),
  140.             $definition,
  141.             $definition->getEntityName(),
  142.             $context
  143.         );
  144.         $search->addPostFilter($queryBoolQuery::FILTER);
  145.     }
  146.     public function addTerm(Criteria $criteriaSearch $searchContext $contextEntityDefinition $definition): void
  147.     {
  148.         if (!$criteria->getTerm()) {
  149.             return;
  150.         }
  151.         $esDefinition $this->registry->get($definition->getEntityName());
  152.         if (!$esDefinition) {
  153.             throw new UnsupportedElasticsearchDefinitionException($definition->getEntityName());
  154.         }
  155.         $query $esDefinition->buildTermQuery($context$criteria);
  156.         $search->addQuery($query);
  157.     }
  158.     public function addQueries(EntityDefinition $definitionCriteria $criteriaSearch $searchContext $context): void
  159.     {
  160.         $queries $criteria->getQueries();
  161.         if (empty($queries)) {
  162.             return;
  163.         }
  164.         $bool = new BoolQuery();
  165.         foreach ($queries as $query) {
  166.             $parsed $this->parser->parseFilter($query->getQuery(), $definition$definition->getEntityName(), $context);
  167.             if ($parsed instanceof MatchQuery) {
  168.                 $score = (string) $query->getScore();
  169.                 $parsed->addParameter('boost'$score);
  170.                 $parsed->addParameter('fuzziness''2');
  171.             }
  172.             $bool->add($parsedBoolQuery::SHOULD);
  173.         }
  174.         $bool->addParameter('minimum_should_match''1');
  175.         $search->addQuery($bool);
  176.     }
  177.     public function addSortings(EntityDefinition $definitionCriteria $criteriaSearch $searchContext $context): void
  178.     {
  179.         foreach ($criteria->getSorting() as $sorting) {
  180.             $search->addSort(
  181.                 $this->parser->parseSorting($sorting$definition$context)
  182.             );
  183.         }
  184.     }
  185.     public function addAggregations(EntityDefinition $definitionCriteria $criteriaSearch $searchContext $context): void
  186.     {
  187.         $aggregations $criteria->getAggregations();
  188.         if (empty($aggregations)) {
  189.             return;
  190.         }
  191.         foreach ($aggregations as $aggregation) {
  192.             $agg $this->parser->parseAggregation($aggregation$definition$context);
  193.             if (!$agg) {
  194.                 continue;
  195.             }
  196.             $search->addAggregation($agg);
  197.         }
  198.     }
  199.     /**
  200.      * Only used for unit tests because the container parameter bag is frozen and can not be changed at runtime.
  201.      * Therefore this function can be used to test different behaviours
  202.      *
  203.      * @internal
  204.      */
  205.     public function setEnabled(bool $enabled): self
  206.     {
  207.         $this->searchEnabled $enabled;
  208.         $this->indexingEnabled $enabled;
  209.         return $this;
  210.     }
  211.     public function isSupported(EntityDefinition $definition): bool
  212.     {
  213.         $entityName $definition->getEntityName();
  214.         return $this->registry->has($entityName);
  215.     }
  216. }