Skip to content
Snippets Groups Projects
EsResponseToResult.php 6.44 KiB
Newer Older
Pavel's avatar
Pavel committed
<?php

namespace IQDEV\ElasticSearch\Converter;

use Elastic\Elasticsearch\Response\Elasticsearch;
use IQDEV\Search\Document\Product;
use IQDEV\Search\Facet\Facet;
use IQDEV\Search\Facet\Item\FacetItemList;
use IQDEV\Search\Facet\Item\FacetItemRange;
use IQDEV\Search\Facet\Item\FacetItemRangeDTO;
use IQDEV\Search\Facet\Type\FacetListType;
use IQDEV\Search\Facet\Type\FacetRangeType;
use IQDEV\Search\Result;

final class EsResponseToResult
{
    public function fromResponse(Elasticsearch $response): Result
    {
        $catalogSearchResult = new Result();

        $data = $response->asArray();
        if (isset($data['hits']['hits'])) {
            foreach ($data['hits']['hits'] as $hit) {
                if (isset($hit['_source'])) {
                    try {
                        $product = $this->productFromArray($hit['_source']);
                        $catalogSearchResult->getProducts()->add($product);
                    } catch (\Throwable $ex) {
                        continue;
                    }
                }
            }

            $catalogSearchResult->setTotal((int)$data['hits']['total']['value']);
        }

        if (isset($data['aggregations']['keyword_facet']['agg_keyword_facet_code']['buckets'])) {
            $buckets = $data['aggregations']['keyword_facet']['agg_keyword_facet_code']['buckets'];
            $bucketsFiltered = [];
            if (isset($data['aggregations']['keyword_facet_filtered']['all_keyword_facet_filtered']['agg_keyword_facet_code']['buckets'])) {
                foreach ($data['aggregations']['keyword_facet_filtered']['all_keyword_facet_filtered']['agg_keyword_facet_code']['buckets'] as $bucket) {
                    $bucketsFiltered[$bucket['key']] = [];
                    foreach ($bucket['agg_keyword_facet_value']['buckets'] as $values) {
                        $bucketsFiltered[$bucket['key']][$values['key']] = $values;
                    }
                }
            }

            foreach ($buckets as $bucket) {
                $code = $bucket['key'];
                if (isset($data['aggregations']["keyword_facet_$code"]['agg_special']['agg_keyword_facet_code']['buckets'])) {
                    $bucketsFiltered[$code] = [];
                    foreach ($data['aggregations']["keyword_facet_$code"]['agg_special']['agg_keyword_facet_code']['buckets'] as $filteredBucket) {
                        if ($filteredBucket['key'] === $code) {
                            foreach ($filteredBucket['agg_keyword_facet_value']['buckets'] as $values) {
                                $bucketsFiltered[$code][$values['key']] = $values;
                            }
                        }
                    }
                }
            }
            $bucketsFiltered = array_filter($bucketsFiltered);

            foreach ($buckets as $bucket) {
                $code = $bucket['key'];
                $valueBucket = $bucket['agg_keyword_facet_value']['buckets'];

                $facet = new Facet(new FacetListType(), $code);

                foreach ($valueBucket as $value) {
                    $count = 0;

                    if (isset($bucketsFiltered[$code][$value['key']])) {
                        $count = $bucketsFiltered[$code][$value['key']]['doc_count'];
                    }

                    $facet->products->add(
                        FacetItemList::create(
                            $value['key'],
                            $count,
                            isset($bucketsFiltered[$code][$value['key']])
                        )
                    );
                }

                $catalogSearchResult->getFacets()->add($facet);
            }
        }

        if (isset($data['aggregations']['number_facet']['agg_number_facet_code']['buckets'])) {
            $buckets = $data['aggregations']['number_facet']['agg_number_facet_code']['buckets'];
            $bucketsFiltered = [];

            if (isset($data['aggregations']['number_facet_filtered']['all_number_facet_filtered']['agg_number_facet_code']['buckets'])) {
                foreach ($data['aggregations']['number_facet_filtered']['all_number_facet_filtered']['agg_number_facet_code']['buckets'] as $bucket) {
                    $bucketsFiltered[$bucket['key']] = $bucket['agg_number_facet_value'];
                }
            }

            foreach ($buckets as $bucket) {
                $code = $bucket['key'];
                if (isset($data['aggregations']["number_facet_$code"]['agg_special']['agg_number_facet_code']['buckets'])) {
                    $bucketsFiltered[$code] = [];
                    foreach ($data['aggregations']["number_facet_$code"]['agg_special']['agg_number_facet_code']['buckets'] as $filteredBucked) {
                        if ($filteredBucked['key'] === $code) {
                            $bucketsFiltered[$code] = $filteredBucked['agg_number_facet_value'];
                        }
                    }
                }
            }
            $bucketsFiltered = array_filter($bucketsFiltered);

            foreach ($buckets as $bucket) {
                $code = $bucket['key'];
                $workBucket = $bucket['agg_number_facet_value'];
                $selectedBuket = $bucketsFiltered[$code] ?? null;

                $facet = new Facet(new FacetRangeType(), $code);
                $facetItem = FacetItemRange::create(
                    FacetItemRangeDTO::create(
                        $workBucket['min'],
                        $workBucket['max'],
                        $workBucket['avg'],
                        $workBucket['sum']
                    ),
                    isset($selectedBuket) ? FacetItemRangeDTO::create(
                        $selectedBuket['min'],
                        $selectedBuket['max'],
                        $selectedBuket['avg'],
                        $selectedBuket['sum']
                    ) : FacetItemRangeDTO::create(),
                    $selectedBuket['count'] ?? $workBucket['count'],
                    isset($selectedBuket)
                );
                $facet->products->add($facetItem);

                $catalogSearchResult->getFacets()->add($facet);
            }
        }

        return $catalogSearchResult;
    }

    private function productFromArray(array $data): Product
    {
        if (!isset($data['data']['id'])) {
            throw new \RuntimeException('id is not set');
        }
        $id = $data['data']['id'];

Pavel's avatar
Pavel committed
        $title = $data['data']['title'] ?? '';
        $info = $data;
Pavel's avatar
Pavel committed

        return new Product($id, $title, $info);
    }
}