bundles/Devkitchen/DocumentIndexingBundle/src/IndexingService/IndexingService.php line 273

Open in your IDE?
  1. <?php
  2.     /**
  3.      * project: Pimcore - Schutzverband Nuernberg Rostbratwuerste
  4.      * User: erikb
  5.      * Year: 2022
  6.      */
  7.     namespace Devkitchen\DocumentIndexingBundle\IndexingService;
  8.     use Devkitchen\DocumentIndexingBundle\DataExtractorService\DataExtractorService;
  9.     use Devkitchen\DocumentIndexingBundle\ElasticSearchService\ElasticSearchService;
  10.     use Devkitchen\DocumentIndexingBundle\Logger\LoggerInterface;
  11.     use Pimcore\Model\Document;
  12.     use Safe\Exceptions\JsonException;
  13.     use Symfony\Component\HttpFoundation\RequestStack;
  14.     class IndexingService {
  15.         /** @var bool  */
  16.         protected bool $enabled;
  17.         /** @var LoggerInterface  */
  18.         protected LoggerInterface $logger;
  19.         /** @var ElasticSearchService  */
  20.         protected ElasticSearchService $elastic;
  21.         /** @var DataExtractorService  */
  22.         protected DataExtractorService $extractor;
  23.         protected string $orderBy 'documentIndex';
  24.         protected string $orderDirection 'asc';
  25.         protected int $resultSize 1000;
  26.         protected int $resultFrom 0;
  27.         public function __construct(bool $enabledElasticSearchService $elasticSearchDataExtractorService $extractorLoggerInterface $logger) {
  28.             $this->enabled $enabled;
  29.             $this->elastic $elasticSearch;
  30.             $this->extractor $extractor;
  31.             $this->logger $logger;
  32.         }
  33.         /**
  34.          * @param string $documentIndexName
  35.          * @param mixed $language
  36.          *
  37.          * @return array
  38.          * @throws JsonException
  39.          */
  40.         public function getDocumentTypes(string $documentIndexName 'default'mixed $language null) {
  41.             $query = [
  42.                 'aggs' => [
  43.                     'field_values' => [
  44.                         'terms' => [
  45.                             'field' => 'documentType',
  46.                             'size' => 1000,
  47.                             'order' => [
  48.                                 '_key' => 'asc'
  49.                             ]
  50.                         ]
  51.                     ]
  52.                 ]
  53.             ];
  54.             $esQuery = [
  55.                 'aggs' => $query['aggs'],
  56.                 'size' => 0
  57.             ];
  58.             $response $this->elastic
  59.                 ->setLanguage$language )
  60.                 ->setDocumentType$documentIndexName )
  61.                 ->search$esQuery );
  62.             $body \Safe\json_decode$response->getBody() );
  63.             if ( $response->getStatusCode() <= 200) {
  64.                 if ($body->hits->total->value 0) {
  65.                     $aggregatedFieldValues = [];
  66.                     foreach($body->aggregations->field_values->buckets as $bucket) {
  67.                         $aggregatedFieldValues[] = $bucket;
  68.                     }
  69.                     return $aggregatedFieldValues;
  70.                 }
  71.             }
  72.             return [];
  73.         }
  74.         /**
  75.          * @param string $filteredByDocumentType
  76.          * @param string $inField
  77.          * @param string $documentIndexName
  78.          * @param mixed $language
  79.          *
  80.          * @return array
  81.          * @throws JsonException
  82.          */
  83.         public function getFieldAggregated(string $filteredByDocumentTypestring $inField 'documentSubtype'string $documentIndexName 'default'mixed $language null) : array  {
  84.             if ( ! $this->enabled ) { return []; }
  85.             $query = [
  86.                 'aggs' => [
  87.                     'field_values' => [
  88.                         'filter' => [
  89.                             'term' => [
  90.                                 'documentType' => $filteredByDocumentType
  91.                             ]
  92.                         ],
  93.                         'aggs' => [
  94.                             'values' => [
  95.                                 'terms' => [
  96.                                     'field' => $inField,
  97.                                     'size' => 1000,
  98.                                     'order' => [
  99.                                         '_key' => 'asc'
  100.                                     ],
  101.                                 ]
  102.                             ]
  103.                         ]
  104.                     ]
  105.                 ]
  106.             ];
  107.             $esQuery = [
  108.                 'aggs' => $query['aggs'],
  109.                 //post filter doesnt affect aggs -> only results
  110.                 //'post_filter' => [
  111.                 //    'term' => [
  112.                 //        'documentType' => $filteredByDocumentType
  113.                 //    ]
  114.                 //],
  115.                 'size' => 0
  116.             ];
  117.             //p_r($esQuery);
  118.             $response $this->elastic
  119.                 ->setLanguage$language )
  120.                 ->setDocumentType$documentIndexName )
  121.                 ->search$esQuery );
  122.             $body \Safe\json_decode$response->getBody() );
  123.             if ( $response->getStatusCode() <= 200) {
  124.                 if ($body->hits->total->value 0) {
  125.                     $aggregatedFieldValues = [];
  126.                     foreach($body->aggregations->field_values->values->buckets as $bucket) {
  127.                         $aggregatedFieldValues[] = $bucket;
  128.                     }
  129.                     return $aggregatedFieldValues;
  130.                 }
  131.             }
  132.             return [];
  133.          }
  134.         /**
  135.          * @param string $type
  136.          * @param array  $subtypes
  137.          * @param string $documentIndexName
  138.          * @param mixed $language
  139.          *
  140.          * @return array|null
  141.          * @throws JsonException
  142.          */
  143.         public function listing(string $type, array $subtypes = [], string $documentIndexName 'default'string $language null) : array | null {
  144.             if ( ! $this->enabled ) { return null; }
  145.             $query = [
  146.                 'bool' => [
  147.                     'must' => [
  148.                         ['term' => [ 'documentType' => $type]],
  149.                         ['term' => [ 'published' => true]]
  150.                     ]
  151.                 ]
  152.             ];
  153.             if (count$subtypes ) > 0) {
  154.                 foreach($subtypes as $subtype) {
  155.                     if ($subtype == 'default') continue;
  156.                     $query['bool']['should'][] = [
  157.                         'term' => [
  158.                             'documentSubtype' => $subtype
  159.                         ]
  160.                     ];
  161.                 }
  162.                 if (isset($query['bool']['should'])) {
  163.                     $query['bool']['minimum_should_match'] = 1;
  164.                 }
  165.             }
  166.             $esQuery = [
  167.                 'query' => $query,
  168.                 'sort' => [
  169.                     $this->orderBy => ['order' => $this->orderDirection]
  170.                 ]
  171.             ];
  172.             $response $this->elastic
  173.                 ->setLanguage$language )
  174.                 ->setDocumentType$documentIndexName )
  175.                 ->search$esQuery$this->resultFrom$this->resultSize );
  176.             $body \Safe\json_decode$response->getBody() );
  177.             if ( $response->getStatusCode() <= 200) {
  178.                 if ($body->hits->total->value 0) {
  179.                     $listing = [];
  180.                     foreach ($body->hits->hits as $hit) {
  181.                         $listing[] = (object)array_merge( ['id' => (int)$hit->_id], (array)$hit->_source);
  182.                     }
  183.                     return $listing;
  184.                 }
  185.             }
  186.             return null;
  187.         }
  188.         /**
  189.          * @param Document $document
  190.          *
  191.          * @return bool
  192.          */
  193.         public function addDocument $document ) : bool {
  194.             if ( ! $this->enabled ) { return false; }
  195.             try {
  196.                 if ($this->extractor->create$document )) {
  197.                     try {
  198.                         $this->elastic->add$this->extractor );
  199.                     }
  200.                     catch (\Exception $exception) {
  201.                         throw new \Exception($exception->getMessage());
  202.                     }
  203.                     return true;
  204.                 }
  205.             }
  206.             catch (\Exception $exception) {
  207.                 $this->logger->log'debug''indexing -> cant create or update, reasion: '.$exception->getMessage());
  208.             }
  209.             return false;
  210.         }
  211.         /**
  212.          * @param Document $document
  213.          *
  214.          * @return stdClass|null
  215.          */
  216.         public function getDocument $document ) : \stdClass null  {
  217.             if ( ! $this->enabled ) { return null; }
  218.             try {
  219.                 if ($this->extractor->create$document )) {
  220.                     $query = [
  221.                         'bool' => [
  222.                             'must' => [
  223.                                 'term' => [
  224.                                     'documentId' => $this->extractor->getId()
  225.                                 ]
  226.                             ]
  227.                         ]
  228.                     ];
  229.                     $esQuery = [
  230.                         'query' => $query,
  231.                         'size' => 1
  232.                     ];
  233.                     $response $this->elastic
  234.                         ->setLanguage$this->extractor->getLanguage() )
  235.                         ->setDocumentType$this->extractor->getElasticIndex() )
  236.                         ->search$esQuery );
  237.                     $body \Safe\json_decode$response->getBody() );
  238.                     if ( $response->getStatusCode() <= 200) {
  239.                         if ($body->hits->total->value 0) {
  240.                             $hit $body->hits->hits[0];
  241.                             return (object)array_merge( ['id' => (int)$hit->_id], (array)$hit->_source);
  242.                         }
  243.                     }
  244.                     //return $this->extractor->getElasticSearchData();
  245.                 }
  246.             }
  247.             catch (\Exception $exception) {
  248.                 $this->logger->log'debug''indexing -> cant get, reasion: '.$exception->getMessage());
  249.             }
  250.             return null;
  251.         }
  252.         /**
  253.          * @param Document $document
  254.          *
  255.          * @return bool
  256.          */
  257.         public function deleteDocument $document) : bool {
  258.             if ( ! $this->enabled ) { return false; }
  259.             try {
  260.                 if ($this->extractor->create$document )) {
  261.                     try {
  262.                         $this->elastic->delete$this->extractor );
  263.                     }
  264.                     catch (\Exception $exception) {
  265.                         throw new \Exception($exception->getMessage());
  266.                     }
  267.                     return true;
  268.                 }
  269.             }
  270.             catch (\Exception $exception) {
  271.                 $this->logger->log'debug''indexing -> cant get, reasion: '.$exception->getMessage());
  272.             }
  273.             return false;
  274.         }
  275.         /**
  276.          * Sets the elasticsearch field with which the result is sorted
  277.          * @param string $orderBy
  278.          *
  279.          * @return IndexingService
  280.          */
  281.         public function setOrderBystring $orderBy ): IndexingService {
  282.             $this->orderBy $orderBy;
  283.             return $this;
  284.         }
  285.         /**
  286.          * sets sorting direction
  287.          * @param string $orderDirection
  288.          *
  289.          * @return IndexingService
  290.          */
  291.         public function setOrderDirectionstring $orderDirection ): IndexingService {
  292.             $this->orderDirection $orderDirection;
  293.             return $this;
  294.         }
  295.         /**
  296.          * Set result size (limit)
  297.          * @param int $resultSize
  298.          *
  299.          * @return IndexingService
  300.          */
  301.         public function setResultSizeint $resultSize ): IndexingService {
  302.             $this->resultSize $resultSize;
  303.             return $this;
  304.         }
  305.         /**
  306.          * set the the beginning of the result (limit)
  307.          * @param int $resultFrom
  308.          *
  309.          * @return IndexingService
  310.          */
  311.         public function setResultFromint $resultFrom ): IndexingService {
  312.             $this->resultFrom $resultFrom;
  313.             return $this;
  314.         }
  315.     }