Skip to content
EsResponseToResult.php 5.82 KiB
Newer Older
Pavel's avatar
Pavel committed
<?php

Nikita Chernykh's avatar
Nikita Chernykh committed
namespace IQDEV\ElasticSearch\Converter\Result;
Pavel's avatar
Pavel committed

use Elastic\Elasticsearch\Response\Elasticsearch;
Nikita Chernykh's avatar
Nikita Chernykh committed
use IQDEV\ElasticSearch\Document\Product;
use IQDEV\ElasticSearch\Facet\FacetResult;
Nikita Chernykh's avatar
Nikita Chernykh committed
use IQDEV\ElasticSearch\Facet\FacetType;
Nikita Chernykh's avatar
Nikita Chernykh committed
use IQDEV\ElasticSearch\Facet\Item\FacetItemList;
use IQDEV\ElasticSearch\Facet\Item\FacetItemRange;
use IQDEV\ElasticSearch\Facet\Item\FacetItemRangeDTO;
use IQDEV\ElasticSearch\Result;
Pavel's avatar
Pavel committed

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'])) {
            $this->parseKeywordFacet($data, $catalogSearchResult);
        }
Pavel's avatar
Pavel committed

        if (isset($data['aggregations']['number_facet']['agg_number_facet_code']['buckets'])) {
            $this->parseNumberFacet($data, $catalogSearchResult);
        }
Pavel's avatar
Pavel committed

        return $catalogSearchResult;
    }
Pavel's avatar
Pavel committed

    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);
    }
Pavel's avatar
Pavel committed

    private function parseKeywordFacet(array $data, Result $catalogSearchResult)
    {
        $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;
Pavel's avatar
Pavel committed
                }
Pavel's avatar
Pavel committed

        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;
                        }
                    }
                }
Pavel's avatar
Pavel committed
            }
        }
        $bucketsFiltered = array_filter($bucketsFiltered);
        foreach ($buckets as $bucket) {
            $code = $bucket['key'];
            $valueBucket = $bucket['agg_keyword_facet_value']['buckets'];

            $facet = new FacetResult(FacetType::LIST, $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);
        }
    private function parseNumberFacet(array $data, Result $catalogSearchResult)
Pavel's avatar
Pavel committed
    {
        $buckets = $data['aggregations']['number_facet']['agg_number_facet_code']['buckets'];
        $bucketsFiltered = [];
Pavel's avatar
Pavel committed

        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'];
            }
        }
Pavel's avatar
Pavel committed

        foreach ($buckets as $bucket) {
            $code = $bucket['key'];
            $workBucket = $bucket['agg_number_facet_value'];
            $selectedBucket = !empty($bucketsFiltered[$code]) ? $bucketsFiltered[$code] : null;
            $facet = new FacetResult(FacetType::RANGE, $code);
            $facetItem = FacetItemRange::create(
                FacetItemRangeDTO::create(
                    $workBucket['min'],
                    $workBucket['max'],
                    $workBucket['avg'],
                    $workBucket['sum']
                ),
                $selectedBucket !== null ? FacetItemRangeDTO::create(
                    $selectedBucket['min'],
                    $selectedBucket['max'],
                    $selectedBucket['avg'],
                    $selectedBucket['sum']
                ) : FacetItemRangeDTO::create(),
                $selectedBucket ? $selectedBucket['count'] : 0,
                $selectedBucket !== null
            );
            $facet->products->add($facetItem);

            $catalogSearchResult->getFacets()->add($facet);
        }
Pavel's avatar
Pavel committed
    }
}