diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php index 897b67d8d46ec..4b879e548824b 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php @@ -49,6 +49,16 @@ class Adapter implements AdapterInterface */ private $temporaryStorageFactory; + /** + * Query Select Parts to be skipped when prepare query for count + * + * @var array + */ + protected $countSqlSkipParts = [ + \Magento\Framework\DB\Select::LIMIT_COUNT => true, + \Magento\Framework\DB\Select::LIMIT_OFFSET => true, + ]; + /** * @param Mapper $mapper * @param ResponseFactory $responseFactory @@ -86,6 +96,7 @@ public function query(RequestInterface $request) $response = [ 'documents' => $documents, 'aggregations' => $aggregations, + 'size' => $this->getSize($query) ]; return $this->responseFactory->create($response); } @@ -114,4 +125,35 @@ private function getConnection() { return $this->resource->getConnection(); } + + /** + * Get rows size + * + * @return int + */ + public function getSize($query) + { + $sql = $this->getSelectCountSql($query); + $parentSelect = $this->getConnection()->select(); + $parentSelect->from(['core_select' => $sql]); + $parentSelect->reset(\Magento\Framework\DB\Select::COLUMNS); + $parentSelect->columns('COUNT(*)'); + $totalRecords = $this->getConnection()->fetchOne($parentSelect); + return (int)$totalRecords; + } + + /** + * Reset limit and offset + * + * @return Select + */ + protected function getSelectCountSql($query) + { + foreach ($this->countSqlSkipParts as $part => $toSkip) { + if ($toSkip) { + $query->reset($part); + } + } + return $query; + } } diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ResponseFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ResponseFactory.php index 776dab93c2dcd..80f7651078e2e 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ResponseFactory.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ResponseFactory.php @@ -68,7 +68,8 @@ public function create($rawResponse) \Magento\Framework\Search\Response\QueryResponse::class, [ 'documents' => $documents, - 'aggregations' => $aggregations + 'aggregations' => $aggregations, + 'size' => $rawResponse['size'] ] ); } diff --git a/lib/internal/Magento/Framework/Search/Response/QueryResponse.php b/lib/internal/Magento/Framework/Search/Response/QueryResponse.php index c2328398e53dc..bc50501d4be88 100644 --- a/lib/internal/Magento/Framework/Search/Response/QueryResponse.php +++ b/lib/internal/Magento/Framework/Search/Response/QueryResponse.php @@ -29,14 +29,23 @@ class QueryResponse implements ResponseInterface */ protected $aggregations; + /** + * Total count of collection + * + * @var int + */ + protected $totalCount; + /** * @param Document[] $documents * @param AggregationInterface $aggregations + * @param Total size int $size */ - public function __construct(array $documents, AggregationInterface $aggregations) + public function __construct(array $documents, AggregationInterface $aggregations, int $size = 0) { $this->documents = $documents; $this->aggregations = $aggregations; + $this->totalCount = $size; } /** @@ -65,4 +74,12 @@ public function getAggregations() { return $this->aggregations; } + + /** + * {@inheritdoc} + */ + public function getTotalCount() + { + return $this->totalCount; + } } diff --git a/lib/internal/Magento/Framework/Search/SearchResponseBuilder.php b/lib/internal/Magento/Framework/Search/SearchResponseBuilder.php index 40fcd493861d7..45d9b7a9d5402 100644 --- a/lib/internal/Magento/Framework/Search/SearchResponseBuilder.php +++ b/lib/internal/Magento/Framework/Search/SearchResponseBuilder.php @@ -42,11 +42,10 @@ public function build(ResponseInterface $response) { /** @var \Magento\Framework\Api\Search\SearchResult $searchResult */ $searchResult = $this->searchResultFactory->create(); - $documents = iterator_to_array($response); $searchResult->setItems($documents); $searchResult->setAggregations($response->getAggregations()); - $searchResult->setTotalCount(count($documents)); + $searchResult->setTotalCount($response->getTotalCount()); return $searchResult; }