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

namespace IQDEV\ElasticSearch\Domain;

use IQDEV\Search\Document\Document;
use IQDEV\Search\Facet\Facet;
use IQDEV\Search\Facet\FacetItemList;
use IQDEV\Search\Facet\FacetItemRange;
use IQDEV\Search\Facet\RangeFacetType;
use IQDEV\Search\Result;
use IQDEV\ElasticSearch\Search\Request;
use Elastic\Elasticsearch\Response\Elasticsearch;
use Http\Promise\Promise;
use IQDEV\Search\Facet\ListFacetType;

final class SearchResultFactory
{
    /**
     * @param Elasticsearch|Promise $response
     * @param Request $request
     * @return Result
     */
    public static function createFromResponse($response, Request $request): Result
    {
        $result = new Result();

        $data = json_decode($response->getBody(), true);

        if (isset($data['hits']['hits'])) {
            foreach ($data['hits']['hits'] as $hit) {
                $result->hits->add(new Document($hit['_id'], $hit));
            }
            $result->numProduct = (int)$data['hits']['total']['value'];
        }

        if ($request->getPagination()) {
            $result->numPages = ceil($result->numProduct / $request->getPagination()->size);
        }

        if (isset($data['aggregations']['keyword_facet']['agg_keyword_facet_code']['buckets'])) {
            $buckets         = $data['aggregations']['keyword_facet']['agg_keyword_facet_code']['buckets'];
            $bucketsFiltered = [];

            $aKeys = array_keys($data['aggregations']);
            foreach ($aKeys as $sKey) {
                if (strpos($sKey, 'keyword_facet_filtered_') !== false) {
                    $sCode = substr($sKey, strlen('keyword_facet_filtered_'));
                    if (isset($data['aggregations'][$sKey]['all_keyword_facet_filtered_' . $sCode]['agg_keyword_facet_code']['buckets'])) {
                        foreach ($data['aggregations'][$sKey]['all_keyword_facet_filtered_' . $sCode]['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;
                            }
                        }
                    }
                }

                if (strpos($sKey, 'all_keyword_facet_filtered_') !== false) {
                    $sCode = substr($sKey, strlen('all_keyword_facet_filtered_'));
                    if (isset($data['aggregations']['all_keyword_facet_filtered_' . $sCode]['agg_keyword_facet_code']['buckets'])) {
                        foreach ($data['aggregations']['all_keyword_facet_filtered_' . $sCode]['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
            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) {
                    if (isset($bucketsFiltered[$bucket['key']])) {
                        continue;
                    }

Pavel's avatar
Pavel committed
                    $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'];
                $valueBucket = $bucket['agg_keyword_facet_value']['buckets'];

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

                foreach ($valueBucket as $value) {
                    $count = !empty($bucketsFiltered) || $result->numProduct === 0 ? 0 : $value['doc_count'];
                    if (isset($bucketsFiltered[$code][$value['key']])) {
                        $count = $bucketsFiltered[$code][$value['key']]['doc_count'];
                    }
                    $facet->items->add(FacetItemList::createFromValue($value['key'], $count));
                }

                $result->facets->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']] = [
                        'data' => $bucket,
                        'min' => $bucket['agg_number_facet_min_value'],
                        'max' => $bucket['agg_number_facet_max_value']
                    ];
                }
            }

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

                $facet       = new Facet(new RangeFacetType, $code);
                $count       = !empty($bucketsFiltered) || $result->numProduct === 0 ? 0 : $bucket['doc_count'];
                $selectedMin = $selectedMax = null;
                if (isset($bucketsFiltered[$code])) {
                    $count       = $bucketsFiltered[$code]['data']['doc_count'];
                    $selectedMin = $bucketsFiltered[$code]['min']['value'];
                    $selectedMax = $bucketsFiltered[$code]['max']['value'];
                }

                $facet->items->add(FacetItemRange::createFromRange(
                    $bucket['agg_number_facet_min_value']['value'],
                    $bucket['agg_number_facet_max_value']['value'],
                    $count,
                    $selectedMin,
                    $selectedMax
                )
                );

                $result->facets->add($facet);
            }
        }

        return $result;
    }
}